if equals not matched but should be. Aduino IDE Serial - serial-port

I'm trying to get a raspberry pi communicating with an arduino over serial, hardware all is setup and there are some comms ok.
Problem I have is the arguments passed are not matched with a if, else if expression but really should be going off what is returned.
SerialCommand library handles what commands trigger what functions. We're only interested in sayHello() for this example. RaspberryPi sends "HELLO HELLO", which should receive "YES HELLO" but I always get "NO HELLO" suggesting no match on the arg HELLO. Obviously what argument was received is echoed back regardless and I receive back what should have matched, HELLO so I'm stumped at this stage, any suggestions?
EDIT: THanks to Thanushan Balakrishnan comment in his answer below, replacing
if(arg == "HELLO")
with the below fixes the problem.
if(strcmp("HELLO", arg) == 0)
_
// Demo Code for SerialCommand Library
// Steven Cogswell
// May 2011
// temp & Humidity
#include <DHT22.h>
#define DHT22_PIN 12
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
// tank water level
int sensorValue = 0;
int constrainedValue = 0;
int tankLevel = 0;
#define TANK_SENSOR 0
#define TANK_EMPTY 0
#define TANK_FULL 1023
/*RelayBrd */
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 4;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 3;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 2;
boolean thisState = LOW;
#include <SerialCommand.h>
#define arduinoLED 13 // Arduino LED on board
SerialCommand sCmd; // The demo SerialCommand object
void setup() {
pinMode(arduinoLED, OUTPUT); // Configure the onboard LED for output
digitalWrite(arduinoLED, LOW); // default to LED off
//mySerial.begin(9600);
//mySerial.println("Ready");
Serial.begin(115200);
// Setup callbacks for SerialCommand commands
sCmd.addCommand("ON", LED_on); // Turns LED on
sCmd.addCommand("OFF", LED_off); // Turns LED off
sCmd.addCommand("getenv", getEnv);
sCmd.addCommand("relaybrd", relayBrd);
sCmd.addCommand("gettanklevel", getTankLevel);
sCmd.addCommand("setlouver", setLouver);
sCmd.addCommand("HELLO", sayHello); // Echos the string argument back
sCmd.addCommand("P", processCommand); // Converts two arguments to integers and echos them back
sCmd.setDefaultHandler(unrecognized); // Handler for command that isn't matched (says "What?")
Serial.println("Ready");
}
void loop() {
sCmd.readSerial(); // We don't do much, just process serial commands
// if (mySerial.available())
// Serial.write(mySerial.read());
// if (Serial.available())
// mySerial.write(Serial.read());
}
void relayBrd(){
char *arg;
char *arg1;
arg = sCmd.next();
arg1 = sCmd.next();
if (arg != NULL) {
//int num = atol(arg);
if (arg1 != NULL) {
int state = atol(arg1);
if (arg == "fan") {
//do something when var equals 1
registerWrite(1, state);
}else if(arg == "water"){
//do something when var equals 2
registerWrite(2, state);
}else if(arg == "mister"){
//do something when var equals 2
registerWrite(3, state);
}else if(arg == "heater"){
//do something when var equals 2
registerWrite(4, state);
}else{
// if nothing else matches, do the default
Serial.print("ERR got:");Serial.print(arg);Serial.println(":");
}
}else{
Serial.println("ERR Relay state missing 1/0");
}
}else{
Serial.println("ERR Relay argument missing fan/water/heater/mister");
}
}
// This method sends bits to the shift register:
void registerWrite(int whichPin, int whichState) {
Serial.print("Relay ");Serial.print(whichPin);Serial.print(" set to ");Serial.println(whichState);
// the bits you want to send
byte bitsToSend = 0;
// turn off the output so the pins don't light up
// while you're shifting bits:
digitalWrite(latchPin, LOW);
// turn on the next highest bit in bitsToSend:
bitWrite(bitsToSend, whichPin, whichState);
// shift the bits out:
shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
// turn on the output so the LEDs can light up:
digitalWrite(latchPin, HIGH);
}
void getEnv(){
Serial.println("26 degC");
DHT22_ERROR_t errorCode;
Serial.print("Requesting data...");
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
Serial.print("Got Data ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
default:
Serial.print("ERR DHT22 ");
Serial.println(errorCode);
}
}
void getTankLevel(){
Serial.println("78% water level");
sensorValue = analogRead( TANK_SENSOR );
constrainedValue = constrain( sensorValue, TANK_EMPTY, TANK_FULL );
tankLevel = map( constrainedValue, TANK_EMPTY, TANK_FULL, 0, 100 );
}
void setLouver() {
char *arg;
arg = sCmd.next();
if (arg != NULL) {
if(arg == "OPEN"){
Serial.println("Louver OPEN");
}else if(arg == "CLOSE"){
Serial.println("Louver CLOSED");
}else{
Serial.print(arg);Serial.println(" not known");
}
}else{
Serial.println("Louver command missing OPEN/CLOSE");
}
}
void LED_on() {
Serial.println("LED on");
digitalWrite(arduinoLED, HIGH);
}
void LED_off() {
Serial.println("LED off");
digitalWrite(arduinoLED, LOW);
}
void sayHello() {
char *arg;
arg = sCmd.next(); // Get the next argument from the SerialCommand object buffer
if (arg != NULL) { // As long as it existed, take it
if (arg == "HELLO") { // As long as it existed, take it
Serial.print("YES ");
Serial.println(arg);
}else{
Serial.print("NO ");
Serial.println(arg);
}
}
else {
Serial.println("Hello Pi");
}
}
void processCommand() {
int aNumber;
char *arg;
Serial.println("We're in processCommand");
arg = sCmd.next();
if (arg != NULL) {
aNumber = atoi(arg); // Converts a char string to an integer
Serial.print("First argument was: ");
Serial.println(aNumber);
}
else {
Serial.println("No arguments");
}
arg = sCmd.next();
if (arg != NULL) {
aNumber = atol(arg);
Serial.print("Second argument was: ");
Serial.println(aNumber);
}
else {
Serial.println("No second argument");
}
}
// This gets set as the default handler, and gets called when no other command matches.
void unrecognized(const char *command) {
Serial.println("What?");
}

In the following function arg is a pointer. So arg has the address of the memory which holds "HELLO". so you should check *arg == "HELLO"
void sayHello()
{
char *arg;
arg = sCmd.next(); // Get the next argument from the SerialCommand object buffer
if (arg != NULL) { // As long as it existed, take it
if (strcmp("HELLO\n", arg) == 0) { <-------------------------- HERE
Serial.print("YES ");
Serial.println(arg);
}else{
Serial.print("NO ");
Serial.println(arg);
}
}
else {
Serial.println("Hello Pi");
}
}

Related

ESP32: Add micro sd card reader on 2nd SPI bus

I am trying to create a music box for my son, but i am having some trouble getting the SD card to work.
The idea is that when we scan a RFID tag we should get the corresponding mp3 file from the SD card.
I am using:
a ESP32 DOIT DEVKIT V1
RFID reader is a RFID-RC522
Micro SD card reader has no brand or model number on it. It just says "Micro sd card adapter" on the back and has 6 pins: cs, sck, mosi, miso, vcc, gnd
My problem is that both the RFID reader and the Micro SD Card reader should use SPI.
With the following code the RFID Card is working well. I just have no idea on how to add the SD Card reader (i have tried using the same pins as the rfid reader and also the HSPI pins, but without success!)
Any help is much appreciated!
#include <SPI.h>
#include <MFRC522.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>
#include "web_index.h"
// Constants
const char *ssid = "****";
const char *password = "****";
const int dns_port = 53;
const int http_port = 80;
const int ws_port = 1337;
// Globals
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
char msg_buf[10];
// Tag reader variables
#define RFID_RC522_RST_PIN 27
#define RFID_RC522_SDA_PIN 5
MFRC522 mfrc522(RFID_RC522_SDA_PIN, RFID_RC522_RST_PIN);
bool rfid_tag_present_prev = false;
bool rfid_tag_present = false;
int _rfid_error_counter = 0;
bool _tag_found = false;
// Volume Variables
int VOLUME = 15;
int VOLUME_NORMAL_MAX = 30;
int VOLUME_LIMIT_MAX = 15;
int VOLUME_MAX = VOLUME_NORMAL_MAX;
int VOLUME_MIN = 0;
int VOLUME_CHANGE_AMOUNT = 1;
bool VOLUME_IS_LIMITED = false;
// Player variables
bool IS_PLAYING = false;
String TRACK_NAME = "-";
String ARTIST_NAME = "-";
// Button variables
const int BUTTON_VOL_DOWN_PIN = 34;
bool BUTTON_VOL_DOWN_STATE = HIGH;
bool BUTTON_VOL_DOWN_PREV_STATE = HIGH;
const int BUTTON_VOL_UP_PIN = 35;
bool BUTTON_VOL_UP_STATE = HIGH;
bool BUTTON_VOL_UP_PREV_STATE = HIGH;
const int BUTTON_STOP_PIN = 32;
bool BUTTON_STOP_STATE = HIGH;
bool BUTTON_STOP_PREV_STATE = HIGH;
const int BUTTON_NEXT_PIN = 33;
bool BUTTON_NEXT_STATE = HIGH;
bool BUTTON_NEXT_PREV_STATE = HIGH;
// Tag IDs
String TAG_TEST = "93 44 5C 92";
String TAG_BACH = "9C CD 69 0F";
/***********************************************************
Functions
*/
void volumeDecrease() {
if (VOLUME > VOLUME_MIN) {
VOLUME = VOLUME - VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
}
}
void volumeIncrease() {
if (VOLUME < VOLUME_MAX) {
VOLUME = VOLUME + VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
} else {
VOLUME = VOLUME_MAX;
broadcastUpdate();
}
}
void updateVolumeLimitState(bool state) {
VOLUME_IS_LIMITED = state;
broadcastUpdate();
}
void broadcastUpdate() {
DynamicJsonDocument doc(1024);
doc["volume"] = VOLUME;
doc["volume_min"] = VOLUME_MIN;
doc["volume_max"] = VOLUME_MAX;
doc["volume_is_limited"] = VOLUME_IS_LIMITED;
doc["is_playing"] = IS_PLAYING;
doc["track_name"] = TRACK_NAME;
doc["artist_name"] = ARTIST_NAME;
char json_string[1024];
serializeJson(doc, json_string);
webSocket.broadcastTXT(json_string);
}
void handleWsTextMessage(uint8_t client_num, uint8_t * payload) {
if ( strcmp((char *)payload, "getValues") == 0 ) {
broadcastUpdate();
} else if ( strcmp((char *)payload, "volume_down_button_click") == 0 ) {
volumeDecrease();
} else if ( strcmp((char *)payload, "volume_up_button_click") == 0 ) {
volumeIncrease();
} else if ( strcmp((char *)payload, "volume_limit_checkbox_on") == 0 ) {
updateVolumeLimitState(true);
} else if ( strcmp((char *)payload, "volume_limit_checkbox_off") == 0 ) {
updateVolumeLimitState(false);
} else { // Message not recognized
Serial.println("[%u] Message not recognized");
}
}
// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num, WStype_t type, uint8_t * payload, size_t length) {
// Figure out the type of WebSocket event
switch (type) {
// Client has disconnected
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", client_num);
break;
// New client has connected
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(client_num);
Serial.printf("[%u] Connection from ", client_num);
Serial.println(ip.toString());
}
break;
// Handle text messages from client
case WStype_TEXT:
// Print out raw message
Serial.printf("[%u] Received text: %s\n", client_num, payload);
handleWsTextMessage(client_num, payload);
break;
// For everything else: do nothing
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
default:
break;
}
}
// Callback: send homepage
void onIndexRequest(AsyncWebServerRequest *request) {
const char* dataType = "text/html";
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
// request->send(SPIFFS, "/index.html", "text/html");
AsyncWebServerResponse *response = request->beginResponse_P(200, dataType, index_html_gz, index_html_gz_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
}
// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request) {
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
request->send(404, "text/plain", "Not found");
}
/***********************************************************
Main
*/
void handleButtons() {
// VOLUME DOWN BUTTON
bool buttonVolDownState = digitalRead(BUTTON_VOL_DOWN_PIN);
if (buttonVolDownState == LOW && BUTTON_VOL_DOWN_PREV_STATE == HIGH) {
Serial.println("button down pressed");
volumeDecrease();
BUTTON_VOL_DOWN_PREV_STATE = LOW;
} else if (buttonVolDownState == HIGH && BUTTON_VOL_DOWN_PREV_STATE == LOW) {
BUTTON_VOL_DOWN_PREV_STATE = HIGH;
}
// VOLUME UP BUTTON
bool buttonVolUpState = digitalRead(BUTTON_VOL_UP_PIN);
if (buttonVolUpState == LOW && BUTTON_VOL_UP_PREV_STATE == HIGH) {
Serial.println("button up pressed");
volumeIncrease();
BUTTON_VOL_UP_PREV_STATE = LOW;
} else if (buttonVolUpState == HIGH && BUTTON_VOL_UP_PREV_STATE == LOW) {
BUTTON_VOL_UP_PREV_STATE = HIGH;
}
// STOP BUTTON
bool buttonStopState = digitalRead(BUTTON_STOP_PIN);
if (buttonStopState == LOW && BUTTON_STOP_PREV_STATE == HIGH) {
Serial.println("button stop pressed");
volumeIncrease();
BUTTON_STOP_PREV_STATE = LOW;
} else if (buttonStopState == HIGH && BUTTON_STOP_PREV_STATE == LOW) {
BUTTON_STOP_PREV_STATE = HIGH;
}
// NEXT BUTTON
bool buttonNextState = digitalRead(BUTTON_NEXT_PIN);
if (buttonNextState == LOW && BUTTON_NEXT_PREV_STATE == HIGH) {
Serial.println("button next pressed");
volumeIncrease();
BUTTON_NEXT_PREV_STATE = LOW;
} else if (buttonNextState == HIGH && BUTTON_NEXT_PREV_STATE == LOW) {
BUTTON_NEXT_PREV_STATE = HIGH;
}
}
String getTagUid() {
String content = "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) {
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
String tag_uid = content.substring(1);
Serial.println("Getting tag uid");
Serial.println(content.substring(1));
return content.substring(1);
}
void checkTagValidity(String tag_uid) {
if (tag_uid == TAG_TEST) {
Serial.println("BLUE TAG");
ARTIST_NAME = "Blue Tag";
TRACK_NAME = "Super Track name";
IS_PLAYING = true;
broadcastUpdate();
} else if (tag_uid == TAG_BACH) {
Serial.println("BACH");
} else {
Serial.println("UNKNOWN CARD: ");
Serial.print(tag_uid);
}
}
void setup() {
// Init buttons
pinMode(BUTTON_VOL_DOWN_PIN, INPUT_PULLUP);
pinMode(BUTTON_VOL_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_STOP_PIN, INPUT_PULLUP);
pinMode(BUTTON_NEXT_PIN, INPUT_PULLUP);
// Start Serial port
Serial.begin(115200);
// Init SPI bus (for the tag reader)
SPI.begin();
// Init the tag reader
mfrc522.PCD_Init();
// Start access point
WiFi.softAP(ssid, password);
// Print our IP address
Serial.println();
Serial.println("AP running");
Serial.print("My IP address: ");
Serial.println(WiFi.softAPIP());
// On HTTP request for root, provide index.html file
server.on("/", HTTP_GET, onIndexRequest);
// 404 page
server.onNotFound(onPageNotFound);
// Start web server
server.begin();
// Start WebSocket server and assign callback
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
}
void loop() {
// Check for button clicks
handleButtons();
// Look for and handle WebSocket data
webSocket.loop();
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if (_rfid_error_counter > 2) {
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
if (result == mfrc522.STATUS_OK) {
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
}
rfid_tag_present = _tag_found;
// rising edge
if (rfid_tag_present && !rfid_tag_present_prev) {
Serial.println("Tag found");
// Get tag uid
String tag_uid = getTagUid();
// Check if valid tag
checkTagValidity(tag_uid);
}
// falling edge
if (!rfid_tag_present && rfid_tag_present_prev) {
Serial.println("Tag gone");
ARTIST_NAME = "-";
TRACK_NAME = "-";
IS_PLAYING = false;
broadcastUpdate();
}
}
Thanks to the comments from #romkey and #RamyHx i got it to work using the same SPI pins.
My problem was that i was using the same pin for the CS of both devices. Once i change it to different CS pins for the rfid and sd card reader it started working.
For the RFID i have used the pin D2, and for the sd card reader i have used the pin D5.
For the rfid i have change #define RFID_RC522_SDA_PIN 5 into #define RFID_RC522_SDA_PIN 2.
For the sd card i have used the code here, which assumes we are using the default pins (with CS connected to pin D5).

How to request for two different URL from Arduino one after another?

In the following code segment I am obtaining latitude, longitude, time, date and speed using GPS SKG13BL with Arduino UNO and then send it to the database via GSM module at every 5 secs. And if the speed (stored to s) returned by GPS is greater than 0, then an LED glows else will be low. After this code segment I am performing the database insertion by calling a URL. This works fine and obtains the results as I thought.
Code:
#include <NeoSWSerial.h>
//#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <NMEAGPS.h>
NeoSWSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX
static const int RXPin = 8, TXPin = 9; //when looking from antenna of gps , Last TTL pin is to be connected to 8 and second one to 9
AltSoftSerial gpsPort(RXPin, TXPin);
static const uint32_t GPSBaud = 9600;
NMEAGPS gps;
gps_fix fix;
uint8_t fixCount = 0;
char dt[15],tm[15],lati[10],longi[10],rno[13]="kl-05-jb-007";
//int block = 0;
enum _parseState {
PS_DETECT_MSG_TYPE,
PS_IGNORING_COMMAND_ECHO,
PS_HTTPPARA_RESPONSE,
PS_HTTPACTION_TYPE,
PS_HTTPACTION_RESULT,
PS_HTTPACTION_LENGTH,
PS_HTTPREAD_LENGTH,
PS_HTTPREAD_CONTENT
};
enum _actionState {
AS_IDLE,
AS_WAITING_FOR_RESPONSE
};
byte actionState = AS_IDLE;
unsigned long lastActionTime = 0;
int s;
byte parseState = PS_DETECT_MSG_TYPE;
char buffer[160],url[160];
byte pos = 0;
int contentLength = 0;
void resetBuffer() {
memset(buffer, 0, sizeof(buffer));
pos = 0;
}
void sendGSM(const char* msg, int waitMs = 500) {
GSM.println(msg);
while(GSM.available()) {
parseATText(GSM.read());
}
//delay(waitMs);
}
void setup()
{
GSM.begin(9600);
Serial.begin(9600);
gpsPort.begin(GPSBaud);
pinMode(13, OUTPUT); //pin 13 to be connected to positive of LED via a resistor
Serial.println(F("Hinder LOADING....."));
Serial.println(F("obtain gps and store data to database"));
Serial.println(F("Testing by : "));
Serial.println(F("Nikhil,Muthumani and Mathews"));
Serial.println();
sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
delay(500);
sendGSM("AT+SAPBR=1,1",3000);
delay(500);
sendGSM("AT+HTTPINIT");
delay(500);
sendGSM("AT+HTTPPARA=\"CID\",1");
delay(500);
}
void loop()
{
unsigned long now = millis();
while (gps.available( gpsPort )) {
fix = gps.read();
//Serial.println(F("b"));
// Once every 5 seconds...
if (++fixCount >= 5) {
//Serial.println(F("a"));
displayInfo();
if(s>0) // Change led state when speed greater than 0 or less than 0
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
//send the next report if previous one is finished
if ( actionState == AS_IDLE ) {
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://hinder.000webhostapp.com/HInsert.php?rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",rno,lati,longi,s,dt,tm );
sendGSM(url);
// lastActionTime = now;
parseState = PS_HTTPPARA_RESPONSE; // a new state
actionState = AS_WAITING_FOR_RESPONSE;
fixCount = 0;
}
}
}
/* if ((gps.statistics.chars < 10) && (millis() > 5000)) {
Serial.println( F("No GPS detected: check wiring.") );
while(true);
block=1;
}*/
while(GSM.available()) {
//lastActionTime = now;
parseATText(GSM.read());
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (fix.valid.location) {
dtostrf( fix.latitude(),7,5,lati);
//sprintf(lati,"%d",fix.latitude(),5);
Serial.print(lati);
Serial.print( ',' );
dtostrf( fix.longitude(),8,5,longi);
//sprintf(longi,"%d",fix.longitude(),5);
Serial.print(longi);
} else {
Serial.print(F("INVALID"));
}
Serial.print(F(" Speed: "));
if (fix.valid.speed) {
s=fix.speed_kph();
Serial.print(s);
Serial.print(F(" KMPH "));
} else {
Serial.print(F("INVALID"));
}
// Shift the date/time to local time
NeoGPS::clock_t localSeconds;
NeoGPS::time_t localTime;
if (fix.valid.date && fix.valid.time) {
using namespace NeoGPS; // save a little typing below...
localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
localTime = localSeconds; // convert back to a structure
}
Serial.print(F(" Date : "));
if (fix.valid.date) {
sprintf(dt,"%02d/%02d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
Serial.print(dt);
} else {
Serial.print(F("INVALID"));
}
Serial.print(F(" Time : "));
if (fix.valid.time) {
if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
sprintf(tm,"%02d:%02d:%02d",localTime.hours,localTime.minutes,localTime.seconds);
Serial.print(tm);
//block=1;
} else {
Serial.print(F("INVALID"));
}
Serial.println();
}
void parseATText(byte b) {
buffer[pos++] = b;
if ( pos >= sizeof(buffer) )
resetBuffer(); // just to be safe
/*
// Detailed debugging
Serial.println();
Serial.print("state = ");
Serial.println(state);
Serial.print("b = ");
Serial.println(b);
Serial.print("pos = ");
Serial.println(pos);
Serial.print("buffer = ");
Serial.println(buffer);*/
switch (parseState) {
case PS_HTTPPARA_RESPONSE:
{
parseState = PS_DETECT_MSG_TYPE;
sendGSM("AT+HTTPACTION=0");
/* while(GSM.available()) {
//lastActionTime = now;
parseATText(GSM.read());
}*/
}
break;
case PS_DETECT_MSG_TYPE:
{
if ( b == '\n' )
resetBuffer();
else {
if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
parseState = PS_IGNORING_COMMAND_ECHO;
}
else if ( b == ':' ) {
//Serial.print("Checking message type: ");
//Serial.println(buffer);
if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
Serial.println("Received HTTPACTION");
parseState = PS_HTTPACTION_TYPE;
}
else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
Serial.println("Received HTTPREAD");
parseState = PS_HTTPREAD_LENGTH;
}
resetBuffer();
}
}
}
break;
case PS_IGNORING_COMMAND_ECHO:
{
if ( b == '\n' ) {
Serial.print("Ignoring echo: ");
Serial.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPACTION_TYPE:
{
if ( b == ',' ) {
Serial.print("HTTPACTION type is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_RESULT;
resetBuffer();
}
}
break;
case PS_HTTPACTION_RESULT:
{
if ( b == ',' ) {
Serial.print("HTTPACTION result is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_LENGTH;
resetBuffer();
}
}
break;
case PS_HTTPACTION_LENGTH:
{
if ( b == '\n' ) {
Serial.print("HTTPACTION length is ");
Serial.println(buffer);
// now request content
GSM.print("AT+HTTPREAD=0,");
GSM.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPREAD_LENGTH:
{
if ( b == '\n' ) {
contentLength = atoi(buffer);
Serial.print("HTTPREAD length is ");
Serial.println(contentLength);
Serial.print("HTTPREAD content: ");
parseState = PS_HTTPREAD_CONTENT;
resetBuffer();
}
}
break;
case PS_HTTPREAD_CONTENT:
{
// for this demo I'm just showing the content bytes in the serial monitor
Serial.write(b);
contentLength--;
if ( contentLength <= 0 ) {
// all content bytes have now been read
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
Serial.print("\n\n\n");
actionState = AS_IDLE;
}
}
break;
}
}
Now I need a modification in this as, when the speed is greater than 0, along with the glowing of the LED, a variable flag (int flag=0; declared globally) is incremented. And flag is set to 0 when the speed is equal to 0. And if the flag value becomes 2 (i.e when speed is greater than 0 for two consecutive readings) I want to send latitude, longitude, date, time and speed at that instant to another database which is also done by calling a URL (url1). And after that I want to send that to the usual database by calling its URL (url).
I did a modification as follows :
if(s>0) // Change led state when speed greater than 0 or less than 0
{
digitalWrite(13, HIGH);
flag++;
}
else
{
digitalWrite(13, LOW);
flag=0;
}
if(flag==2)
{
sprintf(url1, "AT+HTTPPARA=\"URL\",\"http://speed.000webhostapp.com/HInsert.php?rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",rno,lati,longi,s,dt,tm );
sendGSM(url1);
parseState = PS_HTTPPARA_RESPONSE; // a new state
actionState = AS_WAITING_FOR_RESPONSE;
}
This doesn't obtain result as I thought. Can anyone help me. Is it possible to have flag variable working this way in loop(). Is there a problem with my usage of flag or is it another problem.
It is bit tough to make arduino request for two URLs as we would have to handle two separate request and its responses, either the two request would merge in and wont obtain required result or the code would become large that arduino-uno wont be able to handle.
So i found an easy way for doing that, i.e to request for the second PHP page from the first PHP page (which is requested by arduino itself). The only difference between these two request was that the second one need an extra variable. I passed along with the first request so it was available for making request from first page.
I changed arduino code as follows :
First I modified the portion making the check - just after the displayinfo();, as I mentioned in the question, added a flag bit to it. So it become like this :
if(s>0) // s is speed
{
digitalWrite(13, HIGH); //if speed exceeds limit then LED is set to HIGH
flag++;
}
else
{
digitalWrite(13, LOW);
flag=0;
}
The URL for request from arduino was added with the flag variable too. (For the request for second page).
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://hinder.000webhostapp.com/HInsert.php?flag=%d&rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",flag,rno,lati,longi,s,dt,tm );
In the PHP code I added following lines :
if ( $flag == 2 )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://masp203.000webhostapp.com/RTO.php?rno=".$rno."&date=".$date."&time=".$time."&speed=".$speed."&street=".$street."" );
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
This worked just the way I wanted it to be.
Hope this helps some one.

Arduino Sketch - Reading Serial Bytes

I have the following code on my Arduino that constantly checks for a serial command that's sent over TCP using a Wifly library.
What the following code does is split a string like the following when sent over serial:
{power,tv}
It sets these properties accordingly:
char command[32];
char value[32];
It then executes certain methods using sendCommand(command, value); based on the properties set in the loop below.
Keep in mind this works just fine using the Wifly library.
void loop() {
Client client = server.available();
if (client) {
boolean start_data = false;
boolean next = false;
char command[32];
char value[32];
int index = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.print(c);
if (c == '}') {
break;
}
if(start_data == true) {
if(c != ',') {
if(next)
value[index] = c;
else
command[index] = c;
index++;
} else {
next = true;
command[index] = '\0';
index = 0;
}
}
if (c == '{') {
start_data = true;
}
}
}
value[index] = '\0';
client.flush();
client.stop();
sendCommand(command,value);
}
}
Instead of using WiFi I've purchased some Xbee modules. They basically allow you to send serial bytes as well. The only problem is that I'm not quite sure how to handle the looping considering there's no while(client.connected()) anymore. Instead of that I've used while(Serial.available()) thinking that will work, but it doesn't set the value property for some reason.
I get command but I don't get value.
Also I'm not sure whether the loop above is the best way of doing what I'm after, all I know is that it works just fine the way it is. :)
Here is my new loop, which only returns command and not value for some reason:
void loop() {
// if there are bytes waiting on the serial port
if (Serial.available()) {
boolean start_data = false;
boolean next = false;
char command[32];
char value[32];
int index = 0;
while (Serial.available()) {
char c = Serial.read();
Serial.print(c);
if (c == '}') {
break;
}
if(start_data == true) {
if(c != ',') {
if(next)
value[index] = c;
else
command[index] = c;
index++;
} else {
next = true;
command[index] = '\0';
index = 0;
}
}
if (c == '{') {
start_data = true;
}
}
value[index] = '\0';
sendCommand(command,value);
}
}
If the following works with the new loop, I'll be very happy!
void sendCommand(char *command, char *value) {
// do something wonderful with command and value!
}
Got it working by using the following code:
#define SOP '{'
#define EOP '}'
bool started = false;
bool ended = false;
char inData[80];
byte index;
void setup()
{
Serial.begin(9600);
// Other stuff...
}
void loop()
{
// Read all serial data available, as fast as possible
while(Serial.available() > 0)
{
char inChar = Serial.read();
if(inChar == SOP)
{
index = 0;
inData[index] = '\0';
started = true;
ended = false;
}
else if(inChar == EOP)
{
ended = true;
break;
}
else
{
if(index < 79)
{
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
// We are here either because all pending serial
// data has been read OR because an end of
// packet marker arrived. Which is it?
if(started && ended)
{
// The end of packet marker arrived. Process the packet
char *cmd = strtok(inData, ",");
if(cmd)
{
char *val = strtok(NULL, ",");
if(val)
{
sendCommand(cmd, val);
}
}
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
I would change the structure similar to:
while( c != '}') {
if (Serial.available()) {
.
.
.
}
}
Serial characters are received significantly slower then the loop.

Arduino making decision according to a packet received from serial port

The program listen to messages from serial port in the form or where first character (A or D) means analog or digital, the 2nd character - pin, the 3rd character - 1/0 or from 0 to 255. The markers < and > show the beginning and the end of packet.
For example, if packet is received, the light is turned on by digitalWrite(13,1)
But nothing happens. When I send via serial monitor, for instance: light is supposed to blink but it does not. The same with analogue outputs.
bool started = false;
bool ended = false;
char inData[5];
byte index;
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar == '<')
{
index = 0;
started = true;
ended = false;
}
else if (inChar == '>')
{
ended = true;
break;
}
else
{
if (index <= 4)
{
inData[index] = inChar;
index++;
}
}
if (started && ended)
{
if (inData[0] == 'A')
{
pinMode(inData[2],OUTPUT);
analogWrite(inData[2],inData[4]);
}
else if (inData[0] == 'D')
{
if (inData[4] == 1)
{
pinMode(inData[2],OUTPUT);
digitalWrite(inData[2],HIGH);
}
else if (inData[4] == 0)
{
pinMode(inData[2],OUTPUT);
digitalWrite(inData[2],LOW);
}
}
started = false;
ended = false;
index = 0;
}
}
Serial.println("Sending");
}
The following code will allow you to execute a method with an example serial string:
<power,led>
Once it processes this string, it'll execute the following method:
sendCommand(cmd, val);
See below for an example of how to turn on an LED on PIN 11.
#include <avr/pgmspace.h>
int IRledPin = 11;
#define SOP '<'
#define EOP '>'
bool started = false;
bool ended = false;
char inData[80];
byte index;
void setup() {
pinMode(IRledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Read all serial data available, as fast as possible
while (Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == SOP) {
index = 0;
inData[index] = '\0';
started = true;
ended = false;
} else if (inChar == EOP) {
ended = true;
break;
} else {
if (index < 79) {
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
// We are here either because all pending serial
// data has been read OR because an end of
// packet marker arrived. Which is it?
if (started && ended) {
// The end of packet marker arrived. Process the packet
char *cmd = strtok(inData, ",");
if (cmd) {
char *val = strtok(NULL, ",");
if (val) {
sendCommand(cmd, val);
}
}
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
void sendCommand(char *command, char *value) {
if (strcmp(command,"power") == 0) {
power(value);
}
}
void power(char* value) {
if (strcmp(value, "led") == 0) {
digitalWrite(IRledPin, HIGH);
}
}
If the 2nd character is the pin, then you want inData[1] for your pin numbers instead of inData[2].
Why do you go from inData[0] to inData[2]? Wouldn't the second character be in inData[1]?
You're setting the pinMode to the actual value of inData[2]. That means to turn on pin 13, you need to send a carriage return character ('\r').
The code doesn't run below but it should help you to sort out your problem.
What it tries to do is split the inData into the Tokens[] array.
It then turns the ASCII data into integers with the atoi() statement.
Hope it helps.
Got the splitter from Segmentation Fault when using strtok_r
bool started = false;
bool ended = false;
char inData[5];
byte index;
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar == '<')
{
index = 0;
started = true;
ended = false;
}
else if (inChar == '>')
{
ended = true;
break;
}
else
{
inData[index] = inChar;
index++;
}
if (started && ended)
{
// https://stackoverflow.com/questions/2227198/segmentation-fault-when-using-strtok-r
// Splint up input data
char *p = inData;
char *tokens[50];
int i = 0;
while (i < 50) {
tokens[i] = strtok_r(p, ",", &p);
if (tokens[i] == NULL) {
break;
}
i++;
}
if (tokens[0] == '<A')
{
pinMode(tokens[1],OUTPUT);
analogWrite(tokens[2],tokens[3]);
}
else if (token[0] == '<D')
{
if (atoi(token[3]) == 1)
{
pinMode(atoi(token[1]),OUTPUT);
digitalWrite(atoi(token[1]),HIGH);
}
else if (atoi(tokens[3]) == 0)
{
pinMode(atoi(tokens[1]),OUTPUT);
digitalWrite(atoi(tokens[1]),LOW);
}
}
started = false;
ended = false;
index = 0;
}
}

Convert serial.read() into a usable string using Arduino

I'm using two Arduinos to sent plain text strings to each other using NewSoftSerial and an RF transceiver.
Each string is perhaps 20-30 characters in length. How do I convert Serial.read() into a string so I can do if x == "testing statements", etc.?
Unlimited string readed:
String content = "";
char character;
while(Serial.available()) {
character = Serial.read();
content.concat(character);
}
if (content != "") {
Serial.println(content);
}
From Help with Serial.Read() getting string:
char inData[20]; // Allocate some space for the string
char inChar = -1; // Where to store the character read
byte index = 0; // Index into array; where to store the character
void setup() {
Serial.begin(9600);
Serial.write("Power On");
}
char Comp(char* This) {
while (Serial.available() > 0) // Don't read unless there
// you know there is data
{
if(index < 19) // One less than the size of the array
{
inChar = Serial.read(); // Read a character
inData[index] = inChar; // Store it
index++; // Increment where to write next
inData[index] = '\0'; // Null terminate the string
}
}
if (strcmp(inData, This) == 0) {
for (int i=0; i<19; i++) {
inData[i] = 0;
}
index = 0;
return(0);
}
else {
return(1);
}
}
void loop()
{
if (Comp("m1 on") == 0) {
Serial.write("Motor 1 -> Online\n");
}
if (Comp("m1 off") == 0) {
Serial.write("Motor 1 -> Offline\n");
}
}
You can use Serial.readString() and Serial.readStringUntil() to parse strings from Serial on the Arduino.
You can also use Serial.parseInt() to read integer values from serial.
int x;
String str;
void loop()
{
if(Serial.available() > 0)
{
str = Serial.readStringUntil('\n');
x = Serial.parseInt();
}
}
The value to send over serial would be my string\n5 and the result would be str = "my string" and x = 5
I was asking the same question myself and after some research I found something like that.
It works like a charm for me. I use it to remote control my Arduino.
// Buffer to store incoming commands from serial port
String inData;
void setup() {
Serial.begin(9600);
Serial.println("Serial conection started, waiting for instructions...");
}
void loop() {
while (Serial.available() > 0)
{
char recieved = Serial.read();
inData += recieved;
// Process message when new line character is recieved
if (recieved == '\n')
{
Serial.print("Arduino Received: ");
Serial.print(inData);
// You can put some if and else here to process the message juste like that:
if(inData == "+++\n"){ // DON'T forget to add "\n" at the end of the string.
Serial.println("OK. Press h for help.");
}
inData = ""; // Clear recieved buffer
}
}
}
This would be way easier:
char data [21];
int number_of_bytes_received;
if(Serial.available() > 0)
{
number_of_bytes_received = Serial.readBytesUntil (13,data,20); // read bytes (max. 20) from buffer, untill <CR> (13). store bytes in data. count the bytes recieved.
data[number_of_bytes_received] = 0; // add a 0 terminator to the char array
}
bool result = strcmp (data, "whatever");
// strcmp returns 0; if inputs match.
// http://en.cppreference.com/w/c/string/byte/strcmp
if (result == 0)
{
Serial.println("data matches whatever");
}
else
{
Serial.println("data does not match whatever");
}
The best and most intuitive way is to use serialEvent() callback Arduino defines along with loop() and setup().
I've built a small library a while back that handles message reception, but never had time to opensource it.
This library receives \n terminated lines that represent a command and arbitrary payload, space-separated.
You can tweak it to use your own protocol easily.
First of all, a library, SerialReciever.h:
#ifndef __SERIAL_RECEIVER_H__
#define __SERIAL_RECEIVER_H__
class IncomingCommand {
private:
static boolean hasPayload;
public:
static String command;
static String payload;
static boolean isReady;
static void reset() {
isReady = false;
hasPayload = false;
command = "";
payload = "";
}
static boolean append(char c) {
if (c == '\n') {
isReady = true;
return true;
}
if (c == ' ' && !hasPayload) {
hasPayload = true;
return false;
}
if (hasPayload)
payload += c;
else
command += c;
return false;
}
};
boolean IncomingCommand::isReady = false;
boolean IncomingCommand::hasPayload = false;
String IncomingCommand::command = false;
String IncomingCommand::payload = false;
#endif // #ifndef __SERIAL_RECEIVER_H__
To use it, in your project do this:
#include <SerialReceiver.h>
void setup() {
Serial.begin(115200);
IncomingCommand::reset();
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (IncomingCommand::append(inChar))
return;
}
}
To use the received commands:
void loop() {
if (!IncomingCommand::isReady) {
delay(10);
return;
}
executeCommand(IncomingCommand::command, IncomingCommand::payload); // I use registry pattern to handle commands, but you are free to do whatever suits your project better.
IncomingCommand::reset();
Here is a more robust implementation that handles abnormal input and race conditions.
It detects unusually long input values and safely discards them. For example, if the source had an error and generated input without the expected terminator; or was malicious.
It ensures the string value is always null terminated (even when buffer size is completely filled).
It waits until the complete value is captured. For example, transmission delays could cause Serial.available() to return zero before the rest of the value finishes arriving.
Does not skip values when multiple values arrive quicker than they can be processed (subject to the limitations of the serial input buffer).
Can handle values that are a prefix of another value (e.g. "abc" and "abcd" can both be read in).
It deliberately uses character arrays instead of the String type, to be more efficient and to avoid memory problems. It also avoids using the readStringUntil() function, to not timeout before the input arrives.
The original question did not say how the variable length strings are defined, but I'll assume they are terminated by a single newline character - which turns this into a line reading problem.
int read_line(char* buffer, int bufsize)
{
for (int index = 0; index < bufsize; index++) {
// Wait until characters are available
while (Serial.available() == 0) {
}
char ch = Serial.read(); // read next character
Serial.print(ch); // echo it back: useful with the serial monitor (optional)
if (ch == '\n') {
buffer[index] = 0; // end of line reached: null terminate string
return index; // success: return length of string (zero if string is empty)
}
buffer[index] = ch; // Append character to buffer
}
// Reached end of buffer, but have not seen the end-of-line yet.
// Discard the rest of the line (safer than returning a partial line).
char ch;
do {
// Wait until characters are available
while (Serial.available() == 0) {
}
ch = Serial.read(); // read next character (and discard it)
Serial.print(ch); // echo it back
} while (ch != '\n');
buffer[0] = 0; // set buffer to empty string even though it should not be used
return -1; // error: return negative one to indicate the input was too long
}
Here is an example of it being used to read commands from the serial monitor:
const int LED_PIN = 13;
const int LINE_BUFFER_SIZE = 80; // max line length is one less than this
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
Serial.print("> ");
// Read command
char line[LINE_BUFFER_SIZE];
if (read_line(line, sizeof(line)) < 0) {
Serial.println("Error: line too long");
return; // skip command processing and try again on next iteration of loop
}
// Process command
if (strcmp(line, "off") == 0) {
digitalWrite(LED_PIN, LOW);
} else if (strcmp(line, "on") == 0) {
digitalWrite(LED_PIN, HIGH);
} else if (strcmp(line, "") == 0) {
// Empty line: no command
} else {
Serial.print("Error: unknown command: \"");
Serial.print(line);
Serial.println("\" (available commands: \"off\", \"on\")");
}
}
String content = "";
char character;
if(Serial.available() >0){
//reset this variable!
content = "";
//make string from chars
while(Serial.available()>0) {
character = Serial.read();
content.concat(character);
}
//send back
Serial.print("#");
Serial.print(content);
Serial.print("#");
Serial.flush();
}
If you want to read messages from the serial port and you need to deal with every single message separately I suggest separating messages into parts using a separator like this:
String getMessage()
{
String msg=""; //the message starts empty
byte ch; // the character that you use to construct the Message
byte d='#';// the separating symbol
if(Serial.available())// checks if there is a new message;
{
while(Serial.available() && Serial.peek()!=d)// while the message did not finish
{
ch=Serial.read();// get the character
msg+=(char)ch;//add the character to the message
delay(1);//wait for the next character
}
ch=Serial.read();// pop the '#' from the buffer
if(ch==d) // id finished
return msg;
else
return "NA";
}
else
return "NA"; // return "NA" if no message;
}
This way you will get a single message every time you use the function.
Credit for this goes to magma. Great answer, but here it is using c++ style strings instead of c style strings. Some users may find that easier.
String string = "";
char ch; // Where to store the character read
void setup() {
Serial.begin(9600);
Serial.write("Power On");
}
boolean Comp(String par) {
while (Serial.available() > 0) // Don't read unless
// there you know there is data
{
ch = Serial.read(); // Read a character
string += ch; // Add it
}
if (par == string) {
string = "";
return(true);
}
else {
//dont reset string
return(false);
}
}
void loop()
{
if (Comp("m1 on")) {
Serial.write("Motor 1 -> Online\n");
}
if (Comp("m1 off")) {
Serial.write("Motor 1 -> Offline\n");
}
}
If you're using concatenate method then don't forget to trim the string if you're working with if else method.
Use string append operator on the serial.read(). It works better than string.concat()
char r;
string mystring = "";
while(serial.available()){
r = serial.read();
mystring = mystring + r;
}
After you are done saving the stream in a string(mystring, in this case), use SubString functions to extract what you are looking for.
I could get away with this:
void setup() {
Serial.begin(9600);
}
void loop() {
String message = "";
while (Serial.available())
message.concat((char) Serial.read());
if (message != "")
Serial.println(message);
}
Many great answers, here is my 2 cents with exact functionality as requested in the question.
Plus it should be a bit easier to read and debug.
Code is tested up to 128 chars of input.
Tested on Arduino uno r3 (Arduino IDE 1.6.8)
Functionality:
Turns Arduino onboard led (pin 13) on or off using serial command input.
Commands:
LED.ON
LED.OFF
Note: Remember to change baud rate based on your board speed.
// Turns Arduino onboard led (pin 13) on or off using serial command input.
// Pin 13, a LED connected on most Arduino boards.
int const LED = 13;
// Serial Input Variables
int intLoopCounter = 0;
String strSerialInput = "";
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(LED, OUTPUT);
// initialize serial port
Serial.begin(250000); // CHANGE BAUD RATE based on the board speed.
// initialized
Serial.println("Initialized.");
}
// the loop routine runs over and over again forever:
void loop()
{
// Slow down a bit.
// Note: This may have to be increased for longer strings or increase the iteration in GetPossibleSerialData() function.
delay(1);
CheckAndExecuteSerialCommand();
}
void CheckAndExecuteSerialCommand()
{
//Get Data from Serial
String serialData = GetPossibleSerialData();
bool commandAccepted = false;
if (serialData.startsWith("LED.ON"))
{
commandAccepted = true;
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
}
else if (serialData.startsWith("LED.OFF"))
{
commandAccepted = true;
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
}
else if (serialData != "")
{
Serial.println();
Serial.println("*** Command Failed ***");
Serial.println("\t" + serialData);
Serial.println();
Serial.println();
Serial.println("*** Invalid Command ***");
Serial.println();
Serial.println("Try:");
Serial.println("\tLED.ON");
Serial.println("\tLED.OFF");
Serial.println();
}
if (commandAccepted)
{
Serial.println();
Serial.println("*** Command Executed ***");
Serial.println("\t" + serialData);
Serial.println();
}
}
String GetPossibleSerialData()
{
String retVal;
int iteration = 10; // 10 times the time it takes to do the main loop
if (strSerialInput.length() > 0)
{
// Print the retreived string after looping 10(iteration) ex times
if (intLoopCounter > strSerialInput.length() + iteration)
{
retVal = strSerialInput;
strSerialInput = "";
intLoopCounter = 0;
}
intLoopCounter++;
}
return retVal;
}
void serialEvent()
{
while (Serial.available())
{
strSerialInput.concat((char) Serial.read());
}
}
This always works for me :)
String _SerialRead = "";
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available() > 0) //Only run when there is data available
{
_SerialRead += char(Serial.read()); //Here every received char will be
//added to _SerialRead
if (_SerialRead.indexOf("S") > 0) //Checks for the letter S
{
_SerialRead = ""; //Do something then clear the string
}
}
}

Resources