I have written some Arduino code (with help from thisthe post Serial Input BasicsSerial Input Basics). On serial I send some data and, based on certain values sent, certain LEDs will be lit. Here is the Arduino code:
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporaryTemporary array for use when parsing
// variablesVariables to hold the parsed data
//char messageFromPC[numChars] = {0};
int cmd = 0;
int pitch = 0;
int velocity = 0;
int integerFromPC = 0;
int int2FromPC = 0;
boolean newData = false;
void setup() {
// putPut your setup code here, to run once:
Serial.begin(9600);//set baud rate
//Configure pins 2:5 as OUTPUT
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(13,OUTPUT);
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// thisThis temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0.
parseData();
showParsedData();
if(cmd==144 && velocity!=0){
switch(pitch){
case 30:
digitalWrite(2, HIGH);
break;
case 31:
digitalWrite(3, HIGH);
break;
case 32:
digitalWrite(4, HIGH);
break;
case 33:
digitalWrite(5, HIGH);
break;
default:
break;
}
}
if(cmd==144 && velocity==0){
switch(pitch){
case 30:
digitalWrite(2, LOW);
break;
case 31:
digitalWrite(3, LOW);
break;
case 32:
digitalWrite(4, LOW);
break;
case 33:
digitalWrite(5, LOW);
break;
default:
break;
}
}
newData = false;
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminateTerminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() { // splitSplit the data into its parts
char * strtokIndx; // thisThis is used by strtok() as an index
strtokIndx = strtok(tempChars, " "); // getGet the first part - the string
//strcpy(messageFromPC, strtokIndx); // copyCopy it to messageFromPC
cmd = atoi(strtokIndx);
strtokIndx = strtok(NULL, " "); // thisThis continues where the previous call left off
//integerFromPC = atoi(strtokIndx); // convertConvert this part to an integer
pitch = atoi(strtokIndx);
strtokIndx = strtok(NULL, " ");
velocity = atoi(strtokIndx); // convertConvert this part to a float
}
void showParsedData() {
Serial.print("Comm ");
Serial.println(cmd);
Serial.print("Ptch ");
Serial.println(pitch);
Serial.print("Velo ");
Serial.println(velocity);
Serial.println("\n");
}
Then the LED I expect to get lit does, and I can turn it off by:
Now, I want to send this data from a pythonPython (2.7) program which I am reproducing here:
#!/usr/bin/env python
import time
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600)
noteOn = 144
veloMid = 75
veloSilent = 0
def sendData(cmd, pitch, velocity):
global ser
cmd = bytes(cmd)
pitch = bytes(pitch)
velocity = bytes(velocity)
ser.write("<")
ser.write(cmd)
ser.write(pitch)
ser.write(velocity)
ser.write(">")
while 1:
notes = range(30, 34)
for note in notes:
sendData(noteOn, note, veloMid)
time.sleep(2)
sendData(noteOn, note, veloSilent)
The idea was to do the same thing I was doing manually in serial monitor, except using a pythonPython script. But this produces no result. I see the RX and TX pins on the Arduino toggling, so it looks like the program is indeed communicating with the Arduino. In the Python IDE I wrote a few lines as follows to read the data from Arduino:
With above code I receive the following characters in the Python IDE:
I have a feeling there is some mismatch between the data types of the data I am sending between the pythonPython script and the Arduino, but I am not sure exactly what this mismatch might be.