I tried to use the bluetooth module to search for beacons(set up by myself).
And I want to store the received data into SD card.
Initially, I wrote the buffer into SD card, but SD card reads"OOKOK+OK+DOK+DIOK+DISOK+DISCOK+DISCSOOKOK+OK+DOK+DIOK+DISOK+DISCOK+DISCS", the useful data are missed.
Then I wrote the character directly into SD card, but the SD card reads"-1-1-1-1..."
what's the deal here with c=Serial.read(); thingy here?
I thought what you wanted to write to the SD card was what you had read from the ble... that's in the buffer... why on earth would it be suddenly available on the Serial Port? (you sent it, it's gone somewhere, it's not coming back to you :)) )
so this would seem more appropriate
while(ble.available())
{
int r = ble.read();
if (r != -1) { // -1 means error
buffer[count++]=(byte) r; // we add it into the buffer
Serial.write(buffer,count); // we blast the buffer to the console
Serial.println(); // we go to next line so that you can see the string being built
myFile.print((char) r); // we write the byte as a char in the file
if(count >= 128) break; // if we got enough we stop
}
}
(typed here untested)
but once you have emptied (quickly) the incoming buffer you close the file.. so when the loop loops and you get more data, your file write fails... --> this is not the proper way to handle Serial
(see Serial Input Basics)
I have made some changes, ideally, it should get one response each time the switch is on. But I can only get correct response for 2-3 times, then it starts to show "error opening file"
here is my code:
You have not read what I told you to read on how to manage Serial input. Don’t try to have synchronous code to manage an asynchronous protocol... will fail you and clearly it does
Your code should have clear states - one is WAITING (waiting for the switchpin), in that state you only read the switch
when the switch gets ticked then you send the AT command and open the file, write some sort of header if needed and change the state to GATHERING_DATA
In that state you call a c functionrecvWithEndMarkers() you will have learnt to write by reading the serial tutorial I pointed out above, Call and Check against being ‘\n’ for line end and test out the newData flag in a similar way the tutorial was testing receiving A line
If you have the flag set, compare the incoming line with strcmp() or strstr() to see if it is (or contains) “OK+DISCE\r\n” or whatever the last line sent by the module is
If you don’t get “OK+DISCE” then it’s a line describing an answer (you might want to parse it to extract the meaningful data), so add the line buffer you got to the file, change newData to false , and go back just waiting for next line.
If it is “OK+DISCE” then write some sort of trailer in the file and close the file, change newData to false and change the state to WAITING
The cycle will start again - if the switch is still triggered you’ll issue the command again and the gathering will continue.
This type of code structure is what is called a state machine, you should read about this. Your loop basically starts with a
switch(state) {
case WAITING:
....
break;
case GATHERING_DATA:
....
break;
}
// here your code can do other things as long as it’s nit tying up resources for too long
To be more robust then some sort of timeout could also be implemented if staying too long in the GSTHERING_DATA state with no new input and not receiving the end string. Then my need to discard what you saved from that session in the file, so maybe making a note of where you start writing that header to be able to delete from there in case of timeout