I have connected a master Raspberry Pi and a slave Arduino Uno using their respective SDA and SCL pins to enable i2c data transfer. All is well, except that if I transmit a string from RPi to Arduino such as 'Hello123' to the Arduino and later transmit a shorter string such as 'Hello', the Arduino will not recognize the shorter string and will persist with the longer string. If I instead transmit a shorter string such as 'Duh', the resulting string value on the Arduino will by "Duhlo123'. I have tried nulling both the receiving character array and the string, both before and after the interrupt, but no luck. I have tried using both volatile char array and char array, getting the same result. I have tried iteratively nulling the receiving array by inserting (char)0 at each indexed location, but no luck. The transmission of the string back to the RPi from the Arduino has no problems.
Here is the Arduino code:
#include <Wire.h>
#define SLAVE_ADDRESS 0x08
//byte b[12] = {237, 255, 255};
// data buffer
int data[9];
char str0[12];
String dummy1;
String cleanString;
char str[12] = "everything ";
void convertToCleanString (volatile char dummy[]) {
cleanString = "";
cleanString = dummy;
cleanString.remove(0, 1); //remove first character artifact
cleanString.trim();//remove empty space in String
}
/*
This works to receive a string up to 12 characters.
*/
void receiveData(int byteCount) {
// volatile char stro[12];
int counter = 0;
while (Wire.available()) {
str0[counter] = (char)Wire.read();
counter ++;
}
}
void sendData() {
// Wire.write(b, 12);
// 12 character limit set by python data = bus.read_i2c_block_data(address, 99, 12)
// leading or trailing empty characters truncated in Python by string.strip()
Wire.write(str, 12);
// Serial.println("data sent");
}
void setup() {
Serial.begin(9600); // start serial for output
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
// Serial.println("I2C Ready!");
}
void loop() {
delay(1000);
cleanString = "";
if (cleanString != "") {
convertToCleanString(str0);
}
// dummy1 = str0;
// Serial.print(" dummy1 = ");
// Serial.println(dummy1);
Serial.print("cleanString ");
Serial.println(cleanString);
if (cleanString == "Hello") {
Serial.println("Success");
}
char str0[1];
cleanString = "";
Serial.println("pip");
}
Here is the Raspberry Pi Python code.
#!/usr/bin/env python
from time import sleep
import smbus2
bus = smbus2.SMBus(1)
address = 0x08
str1 = 'HelloLLL'
#Sending a string from RPi to Arduino - Working Code - Arduino Stack Exchange
def StringToBytes(val):
retVal = []
for c in val:
retVal.append(ord(c))
return retVal
#http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-$
def writeData(value):
byteValue = StringToBytes(value)
bus.write_i2c_block_data(address,0x00,byteValue) #first byte is 0=comma$
return -1
Get the ASCII number of a character
number = ord(char)
Get the character given by an ASCII number
char = chr(number)
Give the I2C device time to settle
sleep(2)
while 1:
print("Sending ", str1)
writeData(str1)
bus.write_i2c_block_data(address, 0, str1)
sleep(.5)
data = bus.read_i2c_block_data(address, 99, 12)
#slave i2c must not exceed 12 bytes or message will be truncated.
sleep(.5)
print(data)
str1 = ""
convert to string and print result.
Converting between ASCII numbers and characters « Python recipes « ActiveState Code
-between-ascii-numbers-and-characters/
for x in data:
str1 = str1 + chr(x)
str1.strip()
print(str1)
sleep(0.5)
break
I don't understand where or how the Arduino is holding the undesired characters in memory. Thanks for any help.