I have a question that I hoping someone can help with. I would like to modify this segment of Alex's code to function as a slave verse as the Master. Reason, I would like add this code to a slave Anduino (ODS) and have the Master send Telemetry information via the I2C bus version the serial com port. I know it can be done using the wire library but Alex's code is so much more efficient.
#define I2C_SPEED 100000L //100kHz normal mode, this value must be used for a genuine WMP uint8_t rawADC[6]; static uint32_t neutralizeTime = 0; // ************************************************************************************************************ // I2C general functions // ************************************************************************************************************
// Mask prescaler bits : only 5 bits of TWSR defines the status of each I2C request #define TW_STATUS_MASK (1<<TWS7) | (1<<TWS6) | (1<<TWS5) | (1<<TWS4) | (1<<TWS3) #define TW_STATUS (TWSR & TW_STATUS_MASK)
void waitTransmissionI2C() { uint8_t count = 255; while (count-->0 && !(TWCR & (1<<TWINT)) ); if (count<2) { //we are in a blocking state => we don't insist TWCR = 0; //and we force a reset on TWINT register neutralizeTime = micros(); //we take a timestamp here to neutralize the value during a short delay after the hard reset } }
void i2c_getSixRawADC(uint8_t add, uint8_t reg) { i2c_rep_start(add); i2c_write(reg); // Start multiple read at the reg register i2c_rep_start(add +1); // I2C read direction => I2C address + 1 for(uint8_t i = 0; i < 5; i++) { rawADC[i]=i2c_readAck();} rawADC[5]= i2c_readNak(); }
void i2c_writeReg(uint8_t add, uint8_t reg, uint8_t val) { i2c_rep_start(add+0); // I2C write direction i2c_write(reg); // register selection i2c_write(val); // value to write in register }
uint8_t i2c_readReg(uint8_t add, uint8_t reg) { i2c_rep_start(add+0); // I2C write direction i2c_write(reg); // register selection i2c_rep_start(add+1); // I2C read direction return i2c_readNak(); // Read single register and return value }
What I believe is required is something similar to this to make the code work. The wire library to my understanding is Interrupt driven and because of the timing issue with the ODS, this interrupt would create problems.
Follow-up, after giving this more thought, what I need to know is how to mask for the I2C address. I guess I need to learn how the I2C bus communicate.
I believe adding the ability for this ODS to communicate over the I2C bus verse serial is a much better solution. The present version, the serial port is being used for GPS and IMO, this is how the GPS interface should be handled for the MWC. However, what I would like to do is, send the existing Telemetry information from the WMC to the ODS visa I2C bus and display this information in real time. I don't believe this will have an impact on the MWC and may actually improve performance when telemetry communications are required.
As for protocol, I believe using the Existing data structure presently used in the MWC to send data.
Pretty cool idea, but how much more noise are you going to put on this slow bus? You are already reading i2c sensors etc... And I guess you want OSD to be slave, not mwii? anyway I think you need to set TWAR register for address you want to listen on.
We will soon find out. I have two arduinos talking to each other using the wire library, now I need to make the modifications to the WMC to send the data. I am thinking during the design phrase, I will run the bus at 100, then 400 however, I read here, the Bus can run much faster. I am not sure the Arduinos can run at this higher speeds, will have to research that.
The I²C reference design has a 7-bit address space with 16 reserved addresses, so a maximum of 112 nodes can communicate on the same bus. Common I²C bus speeds are the 100 kbit/s standard mode and the 10 kbit/s low-speed mode, but arbitrarily low clock frequencies are also allowed. Recent revisions of I²C can host more nodes and run at faster speeds (400 kbit/s Fast mode, 1 Mbit/s Fast mode plus or Fm+, and 3.4 Mbit/s High Speed mode). These speeds are more widely used on embedded systems than on PCs. There are also other features, such as 16-bit addressing.
You can freely change the I2C bus speed in your code as long as your speed choices are valid for the parts used. For examples just search the Sensors source file for TWBR.