Hi All. Hoping someone can shed some light on an issue I seem to be having.
I am using a PICAXE with I2C to send a 16bit value to an ATtiny85. The ATtiny does some maths and then upon request returns the result to the PICAXE.
At this point I don't know how I can debug my program to know what is actually going on, but my simple I2C program appears to be hanging at times.
I have identified that the issue appears to be in multiples of 128 for some reason, but I am not understanding the root of the problem.
Writing a simple program in the PICAXE (a FOR/NEXT loop 0 to 20000), the ATtiny operates fine until the PICAXE sends 127 at which point the ATtiny returns 79, which is correct. However it continues to return 79 until the PICAXE value hits 255. The ATtiny then starts returning the correct answer again (160) up until the PICAXE hits 382. Things get going again when the PICAXE hits 512 and so on. As can be seen in the program, the LED on PB4 goes HIGH/LOW as expected when the calculated value is returned, but does not go HIGH/LOW when the repeated incorrect value is being returned. During this time the LED just stays OFF/LOW. Once everything gets running normal again (PICAXE hits 255) the LED starts going HIGH/LOW again as it should.
For the life of me, I can't appreciate what or why this is actually happening. I am guessing some sort of buffer issue, but why?
PICAXE simple test program...
for w4 = 0 to 20000
sertxd("Sent: ",#w4,cr)
hi2cout [$26], (b8,b9) 'Send 16bit ADC value in two bytes format to ATtiny85-20SF Math Co-processor for calculation
pause 100 'Give the ATtiny85-20SF time to perform the calculation and be ready with the result
hi2cin [$26], (b2,b3) 'Receive 16bit WORD ohms value in two bytes format from ATtiny85-20SF. 12345 = 123.45 Ohms
sertxd("Returned: ",#w1,cr,cr)
next
end
The rather simple and short FULL ATtiny program...
#include <Wire.h> // Include Arduino TinyWire library for I2C
#define SLAVE_ADDR 0x13 //Define Slave I2C Address. PICAXE equiv = times 2 (Shift value LEFT by 1 bit)
//Arduino 0x12 = PICAXE $24
word adc_value; //Received ADC Value from MASTER
float adc_Ref_Volts = 2.048; //ADC Reference Voltage
int VRef_Volts = 5; //Voltage at top of 1K 0.01%
word adc_Max = 65535; //Maximum possible ADC Value
float adc_Volts; //Calculated Volts referenced from adc_value and adc_Ref_Volts
int R1 = 1000; //Top resistor in voltage divider (1K 0.01%)
float R2; //Final calculated unknown resistor value in Ohms xxx.xx
word R2word; //R2 as WORD
void setup() {
pinMode(4, OUTPUT); //Initialise PB4 as OUTPUT for LED visual confirmation
Wire.begin(SLAVE_ADDR); //Initialize I2C communications as Slave
Wire.onReceive(receiveEvent); //Function to run when data received from master
Wire.onRequest(requestEvent); //Function to run when data requested from master
digitalWrite(4, HIGH);
delay(1);
digitalWrite(4, LOW);
}
void receiveEvent() {
while (0 < Wire.available()) {
adc_value = Wire.read(); //Receive low byte as lower 8 bits
adc_value |= (word)Wire.read() << 8; //Receive high byte and shift left to be high 8 bits of 16bit WORD
}
digitalWrite(4, HIGH); //Activate LED confirming DATA has been received
adc_Volts = (adc_value * adc_Ref_Volts) / adc_Max; //Calculate ADC Volts
R2 = (adc_Volts * R1) / (VRef_Volts - adc_Volts); //Calculate Unknown Resistor Value
R2 = R2 * 100; //Shift decimal 2 places to the right
R2word = R2; //Convert R2 Float to a 16bit WORD
}
void requestEvent() {
Wire.write(R2word & 0xFF); //Send 16bit WORD result in two 8bit bytes via I2C to Master
Wire.write(R2word >> 8);
digitalWrite(4, LOW); //Deactivate LED confirming DATA has been successfully returned
}
void loop() {
}
So what may be going on here?
A couple questions I'd also like answered...
-
Which order to send the two 8 bit bytes to the ATtiny? high 8 first, or low 8 first?
-
Throughout the ATtiny program... high 8 first, or low 8 first? Does it really matter?
Any help here is greatly appreciated.
Cheers,
Mort.