From my android phone app called bluetooth terminal I want to send wording to my sd card connected to the uno pin 4, my hc06 bluetooth module is connected on tx and rx (Pins 1and 0) below is my sketch based around the sd read write example, needless to say it doesnt work, any help would be greatly appreciated. Thanks.
#include <SPI.h>
#include <SD.h>
String readString;
char c;
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) { // pin 4 is selected because were using ethernt shield
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
myFile.println("OK then, you first, say something.....");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
while (Serial.available())
{
delay(3);
c = Serial.read();
readString += c;
}// end while
if (readString.length() >0)
{
Serial.write(c);
readString="";
Serial.print("");
myFile.println("");
} // end if
}
I assume you are intentionally using Serial.print() to send messages to the Bluetooth terminal program.
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).
Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.
Thanks for getting back to me so quickly, i,m seeing lots of references to Dumpfile in sd examples which Ive reproduced below, can you suggest any tweeks that would make what I type on the bluetooth terminal phone app magically appear on my sd card ?
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt");
// if the file is available, write to it:
if (dataFile) {
while (dataFile.available()) {
Serial.write(dataFile.read());
}
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
void loop() {
}
First, write a program where the Arduino reads a message from the bluetooth terminal into a a cstring--a null terminated character array on the Arduino.
Robin2's reference will help you do that.
Then when you have a this data on the Arduino. Write it to the SD card. Your situation is really no different from entering data from the serial monitor and then writing it to the SD card.
About the cstring--a null, is there a particular example I should be looking at in the examples/strings section to get me going ? thanks
No. The ide examples for Examples>08 Strings uses the String Object (String with capital letter S). We are trying to help you avoid using this. This article will help you understand why. The Evils of Arduino Strings | Majenko's Hardware Hacking Blog
cstrings--null terminated character arrays-- are spelled with a small letter s if you refer to them as strings.
If there is something specific in Robin2's tutorial you don't understand, please ask specific questions.
Do you know how to enter text in the top input line of the serial monitor and press send? If so, see if you can use Robin2s example 3 -- receive with start and end markers.
Enter from the serial monitor and see if you can print it back.
Then see if you can store the receivedChars in the sd card.
allend62:
references to Dumpfile in sd examples which Ive reproduced below, can you suggest any tweeks that would make what I type on the bluetooth terminal phone app magically appear on my sd card ?
DumpFile has come up a few times lately, but it is for dumping a file from SD to phone and has nothing to do with making stuff on your phone magically appearing on your SD card. Stick with Robin's serial input stuff, and get to understand it.
I,m using the following code that seems to fit with my wish of sending wording from my android phone terminal app to the uno which then writes those words onto an attached sd card, it doesnt work ! all i get out of the serial monitor is...
Initializing SD card...initialization done.
starting test data reception
I have tried it at 9600 and 11200 baud rate and software serial on pins 4 and 7
any help would be much appreciated
// program to receive test data Iinto a null termnated character
// array (string) and write the string to a SD card
// using methods from Robin2's serial input basics
// by C. Goulding
//#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
const byte csSD = 10;
File testDataFile;
//SoftwareSerial ssPort(4, 7); //(RX, TX)
const byte numChars = 32; //**** adjust this number for the longest data set
// can be up to 255.
char receivedChars[numChars];
boolean newData = false; // true whenever new data comes in
// must be set to false before new data can be read
void setup()
{
Serial.begin(9600);
ssPort.begin(9600);
initSD();
Serial.println(F("starting test data reception"));
delay(3000);
}
void loop()
{
recvWithStartEndMarkers(); // get new data if it is there
if (newData == true) // got new data, save it to SD
{
Serial.print(F("This data just received "));
Serial.println(receivedChars);
testDataFile = SD.open("test.txt", FILE_WRITE);
if (testDataFile)
{
Serial.print(F("Writing to test.txt..."));
testDataFile.println(receivedChars);
testDataFile.close();
Serial.println(F("done."));
}
else
{
Serial.println(F(" $$$$$ error opening test.txt $$$$"));
}
newData = false; // OK ready for more data
}
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (ssPort.available() > 0 && newData == false)
{
rc = ssPort.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 initSD()
{
Serial.print(F("Initializing SD card..."));
if (!SD.begin(csSD))
{
Serial.println(F("############ initialization failed! ########"));
while (1);
}
Serial.println(F("initialization done."));
}
First, I ran with Serial input from the monitor and all was good. Is all correct for the SD write when you use the monitor for input?
I had some issues when using Kai Morich's Serial Bluetooth Terminal on my phone in that there was not an active '<' and '>' key. I changed my start and end marker to @ and $ and all worked as expected.
First, my SD module is on a shield with pin 4 as chip select. So I changed that from pin 10 in the code.
Second, I tested the code with Serial input from the monitor with no software serial or BT.
Can you successfully get to this point?
Third, I re enabled the software serial but changed the RX pin to 5 because of the cs pin change. The bluetooth module TX goes to Arduino ss RX and the bluetooth module RX goest to the Arduino ss TX. The software serial constructor syntax defines the Arduino pins, RX, then TX. You have correctly described the constructor in your code, and the BT module connections need to be crossed TX>RX and RX>TX.
Fourth, I changed the start marker from '<' to '@' and the end marker from '>" to '$' because my android phone terminal did not support < and >.
// program to receive test data Iinto a null termnated character
// array (string) and write the string to a SD card
// using methods from Robin2's serial input basics
// by C. Goulding
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
const byte csSD = 4;//10;
File testDataFile;
SoftwareSerial ssPort(5, 7); //(RX, TX)
const byte numChars = 32; //**** adjust this number for the longest data set
// can be up to 255.
char receivedChars[numChars];
boolean newData = false; // true whenever new data comes in
// must be set to false before new data can be read
void setup()
{
Serial.begin(9600);
ssPort.begin(9600);
initSD();
Serial.println(F("starting test data reception"));
delay(3000);
}
void loop()
{
recvWithStartEndMarkers(); // get new data if it is there
if (newData == true) // got new data, save it to SD
{
Serial.print(F("This data just received "));
Serial.println(receivedChars);
testDataFile = SD.open("test.txt", FILE_WRITE);
if (testDataFile)
{
Serial.print(F("Writing to test.txt..."));
testDataFile.println(receivedChars);
testDataFile.close();
Serial.println(F("done."));
}
else
{
Serial.println(F(" $$$$$ error opening test.txt $$$$"));
}
newData = false; // OK ready for more data
}
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '@';//'<'
char endMarker = '
thankyou i,ll give this another go I have a wiznet ethernet shield which I believe puts the sd card on pin 4, I also am using the same serial bluetooth app by kai morisch as you mentioned previously
thankyou i,ll give this another go I have a wiznet ethernet shield which I believe puts the sd card on pin 4,
The cs pin needs to be correct for the sd module you are using. That is why I stressed that you get the program running with serial input to the arduino then written to the sd card. If the cs is wrong, you will fail at this point.
In fact, if you can't run a sd example program with the test.txt values written into the code with no serial input, then you know where to start.
Good stuff, i can see test.txt written correctly on my sd card now...
"Initializing SD card...initialization done.
starting test data reception
This data just received uno
Writing to test.txt...done.
This data just received hello uno
Writing to test.txt...done."
Is there a way to do say 5 different files called lets say test1.txt, test2.txt etc ? perhaps changing the start markers to differentiate between them ??
Good stuff, i can see test.txt written correctly on my sd card now...
Great. What was the key change you did to make it work properly?
Is there a way to do say 5 different files called lets say test1.txt, test2.txt etc ? perhaps changing the start markers to differentiate between them ??
I think this approach will complicate your code unnecessarily.
I would put the index for the file name or the entire file name in the message with a separator from the rest. Something like @1, Hello World $ @2, Goodbye Moon $
@ sensor2data, 512 $
Then you will use the parsing techniques described in the serial basics tutorial to split the message into is parts.
Creating the file name once you have a differentiator to use, is not complicated.
changing over to pin4 for the sd card magically put things right, ive repeated the setup on my original uno with sd module and still works, thankyou very much, great help, i will look at this multiple test.txt issue and see where i get to