I've built a program that basically functions as an oscilloscope and a function generator. It receives a waveform (string of 256 values between 0 and 255, delimited by commas) from python over Serial, which it then outputs over D0 to D7. The user can send a new waveform by clicking a button on the python end. At the same time, it reads voltage values at A0, stores them into a buffer, then once per second transmits these values to python over the Serial connection.
Everything works well when the program starts, but after sending a few new waveforms from python, it gets stuck on the readFromSerial() function. However, if I open the Serial monitor, it clears up and goes back to working normally. With the monitor open, the user can send as many new waveforms as they like without problem.
When the sendStuff() function is removed, it also works without problems, so I assume there's some conflict between the sending and receiving of data over Serial.
Can anyone explain to me why this could be and how to fix it?
static byte table[256]; //this will hold the values transmitted from python
int i;
byte value;
float N = 256;
float f_clk = 54000;
static float freq;
int amp;
double place;
double M;
int datalen;
char startword;
char bufflen[4]; //stores the datalen information
char buff[1000]; //larger than we need but we can null term to end it
char buff2[10]; //intermediate buffer
const unsigned int numValues = 200;
byte readValues[numValues];
int counter;
int sendflag;
void setup() {
Serial.begin(115200);
for(i=0;i<9;i++){
pinMode(i, OUTPUT);
}
pinMode(13, OUTPUT);
place = 0;
freq = 100; //default values
amp=2.0;
M = (freq*N)/f_clk;
datalen = 767; //default; length of square wave set
counter = 0;
sendflag = 0;
}
void readFromSerial() { //reads the identifier at the start of the incoming data and directs us to the right function
startword = Serial.read();
// Serial.print("startword: "); //for testing purposes
// Serial.println(startword);
if(startword == 'T') {
getTable();
}
else {
while(Serial.available()) { //use up the incoming string so we can try again next time
char t = Serial.read();
}
}
}
void getTable() { //parses the incoming dataset
for(int i=0;i<256;i++) {
table[i] = 0; //clear the table to make room for new values
}
Serial.println("Getting Table!");
char bufflen[4];
Serial.readBytes(bufflen, 3); //first, find length of incoming data
bufflen[3] = '\0'; //null terminate
datalen = atoi(bufflen);
Serial.readBytes(buff, datalen); //read the right number of bytes
buff[datalen] = '\0'; //null terminate
int k = 0;
int i=0;
while(i<datalen){
int j = 0;
while(buff[i]!=44 && buff[i] != '\0') { //while we're on numbers (incoming format is 1,99,100,101,102, etc)
buff2[j]=buff[i];
i++;
j++;
} //now we're at a comma, which we want to ignore
buff2[j] = '\0'; //null term the intermediate buff
table[k] = atoi(buff2); //copy intermediate buff to the table
k++;
i++;
}
}
void makeWaveByPlace() { //output one value from the table, advance the placeholder, then return
i = (int)place;
PORTD = table[i];
place = place + M;
if(place > 255) {
place = place - 255;
}
}
void oscByParts() { //this collects values that we'll be sending to python later
readValues[counter] = analogRead(A0)/4; //get a value
counter++;
if(counter>=numValues) {
sendflag = 1; //stop collecting data
counter = 0; //reset the counter
}
}
void sendStuff() { //this sends the values over serial to python
PORTD = 0; //silence the fungen while sending
for(int i=0;i<numValues;i++) {
Serial.println(readValues[i]);
}
Serial.println("..");
Serial.flush();
//sendflag = 0;
}
void loop() {
long starttime = millis();
while((millis()-starttime)<1000) { //do this for a second
if(Serial.available()) { //if we're getting new data in
readFromSerial();
}
makeWaveByPlace();
if(sendflag == 0) {
oscByParts(); //gathering data to be sent
}
}
if(Serial.available()<=0) { //trying (unsuccessfully) to force it to not interfere with the incoming data
sendStuff(); //send the data we gathered back to python, once every second
}
}