This works well but why is the last byte handled seperately? (see the WHY? comment).
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
// int x = Wire.read(); // receive byte as an integer >>>>>> Why? <<<<
char x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
But if you read the code you will see that I have edited to read the last byte as a char. It only serves to confuse. Is it something to to with terminating the i2c transaction that needs the last 'char' or byte to be received this way?
But if you read the code you will see that I have edited to read the last byte as a char.
Why did you do that?
It only serves to confuse.
Confusion about what?
Is it something to to with terminating the i2c transaction that needs the last 'char' or byte to be received this way?
The receiving is already done, it is about how to interpret the last byte.
This is not clear as I don't know the semantics of what is sent by the I2C master.
Only those semantics can explain why it is originally an int that is read.
My guess is that this is debugging code and that the last byte could not be printed as a char, but as said just a guess.
Do you honestly think that I don't know the difference between print & println? Do you think that I would have got this far with so little knowledge? What a silly answer.
There's something deeper in the wire library I was hoping an expert could answer. The terminating character on the i2c transaction is handled quite differently and requires a fudge at the instantiation level.
Apparently not. The println() adds the line feed so that the printing starts on a new line the next time the receiveEvent() function is called. Otherwise, all the printing would run together.
At time I wonder why I bother with these forums with some of the sarcastic & demeaning answers I get.
I've done the obvious and experimented with the code and this works which indicates that there's nothing special about the last character, it's only a confusing and poorly written example.
void receiveEvent(int howMany)
{
String instring="";
while(0 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
instring=instring+c;
}
Serial.println(instring);
No it is not deeper in the Wire library, you should check the protocol if it is documented.
Or maybe you can post the code of the sender if it is available.
That would allow to do analysis instead of guessing.
The fact that the last byte is interpreted as an integer means something on presentation level.
See OSI model, it is the layer just below the application layer, it is not in the deeper layers.
For completeness of my thoughts, the last byte sent might be a CRC or checksum code.
Those are preferably printed as a number.
As said before, I can only guess if there is no more information.
To give some context, I'm computerising my model railway in Python over an FT232H USB/i2c bridge with MCP23017 port expanders & PCA9685 PWM drivers for both power & servo control for the points. However if you get the pulse width wrong on the servo (by confusing power & servo in the coding) you instantly destroy the servo. So I've decided to use Arduinos as servo drivers as they are completely safe.
However programming the dumb peripherals (port expanders & PWM controllers) require detailed knowledge of the register maps and are quite hard to program. I come to the wire library on the Arduino and it is so easy in comparison that I feel that I must be missing something which is why I ask about the significance of the last byte and why it is handled differently in the examples. And it is very easy, just being able to write a string over the bus is like falling off a log.
This is why I get cross when replies comment that I don't know the difference between Serial.print() and Serial.println().
The wire library is well written and seems very rugged.
Thanks, the context gives some idea what you want to do.
For port expanders like the MCP23017 libraries exists that hide all/ most of the "register magic".
As I understand you need them in python, and I expect that Adafruit has them for circuit-python. You might check their sites.
but that's not the point, the example, as presented, handles the last byte as a special case which implies that there is something special about it. That is what I was asking.
// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(8); // join I2C bus with address #8
Wire.onRequest(requestEvent); // register event
}
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write("hello "); // respond with message of 6 bytes
// as expected by master
}
Based on this sender code my improved guess is that the last byte that is received could have the value 0, 10 or 13, resp char array terminator, linefeed, carriage return. As these are not visually printable characters Nicholas Zambetti seems to have chosen to print it as an integer so it would become visible.
If the last byte was the space after "hello" it would print 32 as the ascii value for space.