Code:
#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!
#include "RP6I2CmasterTWI.h"
/*****************************************************************************/
#define I2C_RP6_BASE_ADR 10 // The default address of the Slave Controller
// on the RP6 Mainboard
/*****************************************************************************/
// 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: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
/*****************************************************************************/
// Rotate function
uint8_t transmit_buffer[10]; // temporary transmit buffer
// A global variable saves space on the heap...
#define CMD_ROTATE 8
#define LEFT 2
#define RIGHT 3
/**
* Rotate function - you can define nearly the same functions as you have on
* the RP6 and just forward the commands with I2C Bus transfers...
* We will make an improved version of this and other functions in another example!
*/
void RP6_rotate(uint8_t desired_speed, uint8_t dir, uint16_t angle)
{
transmit_buffer[0] = 0;
transmit_buffer[1] = CMD_ROTATE;
transmit_buffer[2] = desired_speed;
transmit_buffer[3] = dir;
transmit_buffer[4] = ((angle>>8) & 0xFF);
transmit_buffer[5] = (angle & 0xFF);
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, transmit_buffer, 6 );
}
/*****************************************************************************/
// Read all registers function
uint8_t RP6data[32]; // This array will contain all register values of RP6
// after you called readAllRegisters()
// It is better to keep such big arrays GLOBAL as
// they otherwise fill up the stack in memory...
/**
* This function reads ALL registers available in the standard I2C Bus Slave
* Example program for the Robot Base and outputs their values on the serial interface.
* You will see a lot of zeros when the Motors are not running. The main values that are not
* zero are the two Light Sensors and the two free ADC Channels.
*/
void readAllRegisters(void)
{
I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 0); // Start with register 0...
I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 30); // and read all 30 registers up to
// register Number 29 !
// Now we output the Data we have just read on the serial interface:
writeString_P("\nREADING ALL RP6 REGISTERS:");
uint8_t i = 0;
for(i = 0; i < 30; i++)
{
if(i % 8 == 0) // add some newline chars otherwise everything
writeChar('\n'); // is printed on ONE single line...
else
writeString_P(" | ");
writeChar('#');
writeIntegerLength(i,DEC,2);
writeChar(':');
writeIntegerLength(RP6data[i],DEC,3);
}
writeChar('\n');
}
/**
* Here we demonstrate how to read a few specific registers.
* It is just the same as above, but we only read 4 registers and
* start with register Number 13...
* We also show how to combine values from high and low registers
* back together to a 16 Bit value...
*/
uint8_t Datenaustausch[4]; // temporary transmit buffer
// A global variable saves space on the heap...
#define MOVE_AT_SPEED 5
/**
* Rotate function - you can define nearly the same functions as you have on
* the RP6 and just forward the commands with I2C Bus transfers...
* We will make an improved version of this and other functions in another example!
*/
void RP6_moveAtSpeed(uint8_t leftspeed, uint8_t rightspeed)
{
Datenaustausch[0] = 0;
Datenaustausch[1] = MOVE_AT_SPEED;
Datenaustausch[2] = leftspeed;
Datenaustausch[3] = rightspeed;
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, Datenaustausch, 4 );
}
void ADC1(void)
{
uint8_t adc1[2];
I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 25);
I2CTWI_readBytes(I2C_RP6_BASE_ADR, adc1, 2);
writeString_P("ADC1:\n");
writeInteger(adc1[0], DEC);
writeInteger(adc1[1], DEC);
writeString_P("\n");
writeString_P("ADC1 Kanal:"); writeInteger(adc1[0] + (adc1[1]<<8), DEC);
writeString_P("\n");
setCursorPosLCD(1, 11);
writeIntegerLengthLCD(adc1[0] + (adc1[1]<<8), DEC, 3);
}
uint8_t Schaltbefehl[4];
#define INT1_SET_H 13
#define INT1_SET_L 14
void Relaisplatine(void)
{
Schaltbefehl[0] = 0;
Schaltbefehl[1] = INT1_SET_H;
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, Schaltbefehl, 2 );
mSleep(2000);
Schaltbefehl[0] = 0;
Schaltbefehl[1] = INT1_SET_L;
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, Schaltbefehl, 2 );
}
uint8_t ServobefehlR[2];
#define SERVO_RECHTSLAUF 15
void Servo_Rechtslauf(void)
{
ServobefehlR[0] = 0;
ServobefehlR[1] = SERVO_RECHTSLAUF;
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, ServobefehlR, 2 ); // Impulsstart
}
uint8_t ServobefehlL[2];
#define SERVO_LINKSLAUF 16
void Servo_Linkslauf(void)
{
ServobefehlL[0] = 0;
ServobefehlL[1] = SERVO_LINKSLAUF;
I2CTWI_transmitBytes(I2C_RP6_BASE_ADR, ServobefehlL, 2 ); // Impulsstart
}
void readLightSensors(void)
{
uint8_t lightSens[4];
I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 13); // Start with register 13 (LSL_L)...
I2CTWI_readBytes(I2C_RP6_BASE_ADR, lightSens, 4); // and read all 4 registers up to
// register Number 16 (LSR_H) !
writeString_P("Light Sensor registers:\n");
writeString_P(" | LSL_L:"); writeInteger(lightSens[0], DEC);
writeString_P(" | LSL_H:"); writeInteger(lightSens[1], DEC);
writeString_P(" | LSR_L:"); writeInteger(lightSens[2], DEC);
writeString_P(" | LSR_H:"); writeInteger(lightSens[3], DEC);
writeString_P("\n\n Light Sensor Values:");
writeString_P(" | LSL:"); writeInteger(lightSens[0] + (lightSens[1]<<8), DEC);
writeString_P(" | LSR:"); writeInteger(lightSens[2] + (lightSens[3]<<8), DEC);
writeChar('\n');
setCursorPosLCD(1, 3);
writeIntegerLengthLCD(lightSens[0] + (lightSens[1]<<8), DEC, 4);
setCursorPosLCD(1, 11);
writeIntegerLengthLCD(lightSens[2] + (lightSens[3]<<8), DEC, 4);
}
/*****************************************************************************/
// Main function - The program starts here:
int main(void)
{
initRP6Control(); // Always call this first! The Processor will not work
// correctly otherwise.
initLCD(); // Initialize the LC-Display (LCD)
// Always call this before using the LCD!
writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n");
// IMPORTANT:
I2CTWI_initMaster(100); // Initialize the TWI Module for Master operation
// with 100kHz SCL Frequency
// Register the event handlers:
I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
// Play two sounds:
sound(180,80,25);
sound(220,80,25);
setLEDs(0b1111); // Turn all LEDs on!
showScreenLCD("################", "################");
mSleep(500);
showScreenLCD("I2C-Master", "Example Program 1");
mSleep(1000);
// ---------------------------------------
setLEDs(0b0000); // All LEDs off!
while(true)
{
// We check the buttons - just like the buttons example - but here we
// generate several I2C Bus requests and commands when a key
// is pressed AND released again...
uint8_t key = checkReleasedKeyEvent();
if(key)
{
switch(key)
{
case 1: // Increment a counter and send value to LEDs of the
// Slave Controller:
setLEDs(0b0001);
showScreenLCD("ADC1", "KANAL:");
ADC1();
break;
case 2: // Read and display ALL registers of the slave controller:
setLEDs(0b0010);
showScreenLCD("Servo", "Steuerfunktion");
Servo_Linkslauf();
break;
case 3: // Read the light sensors and show value on display:
setLEDs(0b0100);
showScreenLCD("Servo", "Steuerfunktion");
Servo_Rechtslauf();
break;
case 4: // Rotate a very small distance to the left:
setLEDs(0b1000);
showScreenLCD("Fahren", "TEST");
RP6_moveAtSpeed(70,70);
break;
case 5: // Rotate a very small distance to the right:
setLEDs(0b1001);
showScreenLCD("Relaisplatine", "Schaltfunktion");
Relaisplatine();
break;
}
}
}
return 0;
}
Lesezeichen