I have written some Arduino code (with help from the post Serial 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]; // Temporary array for use when parsing
// Variables 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() {
// Put 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);
// This 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'; // Terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() { // Split the data into its parts
char * strtokIndx; // This is used by strtok() as an index
strtokIndx = strtok(tempChars, " "); // Get the first part - the string
//strcpy(messageFromPC, strtokIndx); // Copy it to messageFromPC
cmd = atoi(strtokIndx);
strtokIndx = strtok(NULL, " "); // This continues where the previous call left off
//integerFromPC = atoi(strtokIndx); // Convert this part to an integer
pitch = atoi(strtokIndx);
strtokIndx = strtok(NULL, " ");
velocity = atoi(strtokIndx); // Convert 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");
}
Now this works perfectly with sending data from the Arduino's serial monitor, so for example if I type the following on serial monitor:
<144 30 45>
Then the LED I expect to get lit does, and I can turn it off by:
<144 30 0>
Now, I want to send this data from a Python (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 Python 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:
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=5)
while True:
data_raw = ser.read()
print data_raw
With above code I receive the following characters in the Python IDE:
C
o
m
m
P
t
c
h
V
e
l
o
I have a feeling there is some mismatch between the data types of the data I am sending between the Python script and the Arduino, but I am not sure exactly what this mismatch might be.
Why am I not seeing the values of cmd, pitch and veocity being printed out from the serial.read() although the other strings "Comm Ptch Velo" are printed?
What dataype is serial.write passing on that might than be causing mismatch with my Arduino code?
Ctrl+K
to have your browser do this for you. It was hard work changing your tags (from I don't know where) into what works here.