Code:
/*****************************************************************************/
// Includes:
#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!
#include "RP6I2CmasterTWI.h" // I2C Master Library
#include "../../RP6Lib/standard/standard.h"
#include "RP6Control_I2CMasterLib.h"
/**************************ACS_state_changed**********************************/
//siehe standard.c
/********************bumpers_state_changed************************************/
//siehe standard.c
/**
* And the RC5 Event Handler is the same as on the Robot Base, too.
*/
void receiveRC5Data(RC5data_t rc5data)
{
// Output the received data:
writeString_P("RC5 Reception --> Toggle Bit:");
writeChar(rc5data.toggle_bit + '0');
writeString_P(" | Device Address:");
writeInteger(rc5data.device, DEC);
writeString_P(" | Key Code:");
writeInteger(rc5data.key_code, DEC);
writeChar('\n');
}
/**
* This is a new Event Handler and it gets called when the Battery Voltage
* is getting low! The Parameter isVoltageLow is true, when the voltage
* is low and false, when the voltage is OK.
*/
/*
void batteryVoltageLow(uint8_t isVoltageLow)
{
if(isVoltageLow)
{
writeString_P("\nBattery Voltage low: ");
// Send Battery voltage to UART:
writeIntegerLength((((adcBat/102.4f)+0.1f)), DEC, 2);
writeChar('.');
writeIntegerLength((((adcBat/1.024f)+10)), DEC, 2);
writeString_P("V\n");
}
else
{
writeString_P("\nBattery Voltage is OK!\n");
}
}
*/
/********************print_all_sensor_values*********************/
//siehe standard.c
/************************************************************/
/************** * Heartbeat function*************************/
//siehe standard.c
/************************************************************/
/***************************watchDog_Request**********************/
// siehe standard.c
/*****************************************************************/
// I2C Requests:
/**
* The I2C_requestedDataReady Event Handler is now a lot smaller.
* It is free for your own request routines.
* You can put them in the Block of the if condition.
* (similar to the RP6 Base Example programs...)
*/
void I2C_requestedDataReady(uint8_t dataRequestID)
{
// We need to check if this is an INT0 Request from the Robot Base unit.
// The Function call inside the if condition returns true if it was an
// interrupt request, so we have to negate it here and if it was NOT
// an interrupt request from the Robot base we can check any other sensors
// from which you may have requested data...
if(!checkRP6Status(dataRequestID))
{
// Here you can Check other sensors/microcontrollers with their own
// request IDs - if there are any...
}
}
/******************************I2C Error handler******************************/
// siehe standard.c
/*****************************************************************************/
// Main function - The program starts here:
int main(void)
{
initRP6Control();
initLCD();
writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n");
writeString_P("\nInterrupts - part 2...\n");
// ---------------------------------------
// The Event Handlers can be set the same way as with the
// RP6Lib:
ACS_setStateChangedHandler(acsStateChanged);
BUMPERS_setStateChangedHandler(bumpersStateChanged);
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);
// New LowBat Event Handler:
BATTERY_setLowVoltageHandler(batteryVoltageLow);
// New Watchdog Request Event Handler:
WDT_setRequestHandler(watchDogRequest);
// ---------------------------------------
// Init TWI Interface:
I2CTWI_initMaster(100);
I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
sound(180,80,25);
sound(220,80,25);
setLEDs(0b1111);
showScreenLCD("################", "################");
mSleep(500);
showScreenLCD("I2C-Master", "Example Program 3");
mSleep(1000);
setLEDs(0b0000);
clearLCD();
accuspannung();
mSleep(1500);
// ---------------------------------------
// Setup ACS power:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_ACS_POWER, ACS_PWR_MED);
// Enable Watchdog for Interrupt requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
// Enable timed watchdog requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true);
showScreenLCD("ACS Status:", "");
startStopwatch1();
startStopwatch2();
while(true)
{
task_LCDHeartbeat();
task_checkINT0();
task_I2CTWI();
accuzustand();
}
return 0;
}
standard.c:
Code:
#include "standard.h"
#include "RP6ControlLib.h"
#include "RP6I2CmasterTWI.h"
#include "RP6Control_MultiIOLib.h"
#include "RP6Control_I2CMasterLib.h"
#include "RP6ControlServoLib.h"
#include "RP6Control_OrientationLib.h"
/************************ Write a floating point number to the LCD or terminal. ******/
/*
* Example:
*
* // Write a floating point number to the LCD (no exponent):
* writeDoubleLCD(1234567.890, 11, 3);
*
* The value of prec (precision) defines the number of decimal places.
* For 32 bit floating point variables (float, double ...) 6 is
* the max. value for prec (7 relevant digits).
* The value of width defines the overall number of characters in the
* floating point number including the decimal point. The number of
* pre-decimal positions is: (width - prec - 1).
*/
void writeDoubleLCD(double number, uint8_t width, uint8_t prec)
{char buffer[width + 1];
dtostrf(number, width, prec, &buffer[0]);
writeStringLCD(&buffer[0]);
}
/* Write a floating point number to the terminal (no exponent):
writeDoubleLCD(1234567.890, 11, 3);
*/
void writeDouble(double number, uint8_t width, uint8_t prec)
{char buffer[width + 1];
dtostrf(number, width, prec, &buffer[0]);
writeString(&buffer[0]);
}
/**************accuspannungsanzeige********/
void accuspannung(void) // accuspannung ausgeben
{
// Voltage & current sensor test:
multiio_init();
LTC2990_measure();
setCursorPosLCD(0, 0);
//writeStringLCD("BAT Current: ");
//writeDoubleLCD(cbat, 6, 1);
writeStringLCD(" accu: ");
writeDoubleLCD(vbat, 4, 1);
writeStringLCD( " V");
}
/**************accuzustand********/
void accuzustand(void) // accuspannung abfragen und signalisieren
{
LTC2990_measure();
if (vbat < 6)
{
buzzer(330);
mSleep(200);
buzzer(330);
mSleep(200);
}
}
/*****************************************************************************/
// I2C Error handler
/**
* This function gets called automatically if there was an I2C Error like
* the slave sent a "not acknowledge" (NACK, error codes e.g. 0x20 or 0x30).
* The most common mistakes are:
* - using the wrong address for the slave
* - slave not active or not connected to the I2C-Bus
* - too fast requests for a slower slave
* Be sure to check this if you get I2C errors!
*/
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("\nI2C ERROR --> TWI STATE IS: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
/*******************LCD_heart_beat************************/
void task_LCDHeartbeat(void)
{
if(getStopwatch1() > 500)
{
static uint8_t heartbeat = false;
if(heartbeat)
{
clearPosLCD(0, 15, 1);
heartbeat = false;
}
else
{
setCursorPosLCD(0, 15);
writeStringLCD_P("*");
heartbeat = true;
printAllSensorValues();
}
setStopwatch1(0);
}
}
/*********************watchdod_request*****************/
/*
* Now we have a second "Heartbeat" display
* which shows if the Controller still reacts on
* the Watchdog requests from the Slave Controller!
* And it also shows if the slave Controller is
* still up and running.
*
* It will blink with a rate of about 2Hz when
* the watchdog requests are still active.
*/
void watchDogRequest(void)
{
static uint8_t heartbeat2 = false;
if(heartbeat2)
{
clearPosLCD(0, 14, 1);
heartbeat2 = false;
}
else
{
setCursorPosLCD(0, 14);
writeStringLCD_P("#");
heartbeat2 = true;
}
}
/*******************print_all_sensor_values*****************/
/*
* This function prints out all ADC values and motor parameters:
* power, desired speed, measured speed and driven distance.
*
* It first calls "getAllSensors()" from the library which reads all
* the sensor values we use here from the Slave Controller.
* Then you can use just the same variables as on the RP6Base to get
* the ADC values.
*/
void printAllSensorValues(void)
{
getAllSensors();
writeString_P("\nRead Sensor Values:\n");
writeString_P("PL:");writeIntegerLength(mleft_power,DEC,3);
writeString_P(" | PR:");writeIntegerLength(mright_power,DEC,3);
writeString_P(" | VL:");writeIntegerLength(mleft_speed,DEC,3);
writeString_P(" | VR:");writeIntegerLength(mright_speed,DEC,3);
writeString_P(" | DL:");writeIntegerLength(mleft_des_speed,DEC,3);
writeString_P(" | DR:");writeIntegerLength(mright_des_speed,DEC,3);
writeChar('\n');
writeString_P("DSTL:");writeIntegerLength(mleft_dist,DEC,5);
writeString_P(" | DSTR:");writeIntegerLength(mright_dist,DEC,5);
writeChar('\n');
writeString_P("LSL:");writeIntegerLength(adcLSL,DEC,4);
writeString_P(" | LSR:");writeIntegerLength(adcLSR,DEC,4);
writeString_P(" | MCL:");writeIntegerLength(adcMotorCurrentLeft,DEC,4);
writeString_P(" | MCR:");writeIntegerLength(adcMotorCurrentRight,DEC,4);
writeString_P(" | BAT:");writeIntegerLength(adcBat,DEC,4);
writeString_P(" | AD0:");writeIntegerLength(adc0,DEC,4);
writeString_P(" | AD1:");writeIntegerLength(adc1,DEC,4);
writeChar('\n');
}
/******************acs_State_Changed*****************************/
void acsStateChanged(void)
{
writeString_P("ACS state changed L: ");
if(obstacle_left)
{
writeChar('o');
setCursorPosLCD(1, 12);
writeStringLCD_P("LEFT");
}
else
{
writeChar(' ');
clearPosLCD(1, 12, 4);
}
writeString_P(" | R: ");
if(interrupt_status.obstacleRight)
{
writeChar('o');
setCursorPosLCD(1, 0);
writeStringLCD_P("RIGHT");
}
else
{
writeChar(' ');
clearPosLCD(1, 0, 5);
}
if(obstacle_left && obstacle_right)
{
externalPort.LEDS = 0b0110;
writeString_P(" MIDDLE!");
setCursorPosLCD(1, 7);
writeStringLCD_P("MID");
}
else
{
externalPort.LEDS = 0b0000;
clearPosLCD(1, 7, 3);
}
if(obstacle_left)
externalPort.LED1 = true;
if(obstacle_right)
externalPort.LED4 = true;
outputExt();
if(obstacle_left && obstacle_right)
{
sound(140,10,0);
}
else
{
if(obstacle_left)
sound(100,5,0);
if(obstacle_right)
sound(120,5,0);
}
writeChar('\n');
}
/*****************bumpers_state_changed*********************/
void bumpersStateChanged(void)
{
// Bumper status changed, output current state and play sounds:
writeString_P("Bumpers changed: ");
if(bumper_right && bumper_left)
{
writeString_P("MIDDLE!");
sound(200,100,0);
}
else
{
if(bumper_left)
{
writeString_P("LEFT!");
sound(200,50,10);
sound(150,20,0);
}
else if(bumper_right)
{
writeString_P("RIGHT!");
sound(200,50,10);
sound(150,20,0);
}
else
{
writeString_P("FREE!");
}
}
writeChar('\n');
}
/**********receive_RC5_data***************************/
/*
void receiveRC5Data(RC5data_t rc5data)
{
// Output the received data:
writeString_P("RC5 Reception --> Toggle Bit:");
writeChar(rc5data.toggle_bit + '0');
writeString_P(" | Device Address:");
writeInteger(rc5data.device, DEC);
writeString_P(" | Key Code:");
writeInteger(rc5data.key_code, DEC);
writeChar('\n');
}
*/
/************battery_voltage_low*************************/
void batteryVoltageLow(uint8_t isVoltageLow)
{
if(isVoltageLow)
{
writeString_P("\nBattery Voltage low: ");
// Send Battery voltage to UART:
writeIntegerLength((((adcBat/102.4f)+0.1f)), DEC, 2);
writeChar('.');
writeIntegerLength((((adcBat/1.024f)+10)), DEC, 2);
writeString_P("V\n");
}
else
{
writeString_P("\nBattery Voltage is OK!\n");
}
}
Lesezeichen