How to upload data to thingsSpaek using arduino and esp8266? - arduino

I am using an arduino and an esp8266 wifi module to upload data to the things spaek site.I found this code on instructables site inorder to upload random data to the things speak site but it is giving erro on case 3.
here is the code
#include <SoftwareSerial.h>
#define DEBUG true
#define RX 2
#define TX 3
String HOST = "api.thingspeak.com";
String PORT = "80";
String AP = "AP NAME";
String PASS = "AP PASSWORD";
String API = "---------";
String field = "field1";
int countTrueCommand;
int countTimeCommand;
boolean found = false;
int valSensor = 1;
SoftwareSerial esp8266(RX,TX);
void setup() {
Serial.begin(9600);
esp8266.begin(115200);
sendCommand("AT",5,"OK");
sendCommand("AT+CWMODE=1",5,"OK");
sendCommand("AT+CWJAP=""+ AP +"",""+ PASS +""",15,"OK");
countTrueCommand = 0;
}
void loop() {
String getData = "GET /update?api_key="+ API +"&"+ field
+"="+String(valSensor);
switch(countTrueCommand) {
case 0: sendCommand("AT",5,"OK");break;
case 1: sendCommand("AT+RST",10,"invalid");break;
case 2: sendCommand("AT+CIPMUX=1",5,"OK"); break;
case 3: sendCommand("AT+CIPSTART=0,"TCP","+ HOST +","+ PORT,15,"OK");
break;
case 4: sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
break;
case 5: esp8266.println(getData);delay(1500);countTrueCommand++; break;
case 6: sendCommand("AT+CIPCLOSE=0",5,"OK"); break;
case 7:
Serial.println(valSensor);
Serial.print(getData);
Serial.print(",");
Serial.println(getData.length());
valSensor = random(100000); // random value, change with sensor value if
using sensor
countTrueCommand = 0;
delay(10000);
break;
}
}
void sendCommand(String command, int maxTime, char readReplay[]) {
Serial.print(countTrueCommand);
Serial.print(". at command => ");
Serial.print(command);
Serial.print(" ");
while(countTimeCommand < (maxTime*1))
{
esp8266.println(command);//at+cipsend
if(esp8266.find(readReplay))//ok
{
found = true;
break;
}
countTimeCommand++;
}
if(found == true)
{
Serial.println("OYI");
countTrueCommand++;
countTimeCommand = 0;
}
if(found == false)
{
Serial.println("Fail");
countTrueCommand = 0;
countTimeCommand = 0;
}
found = false;
}
i am getttina an error on case 3 as
exit status 1
unable to find string literal operator 'operator""TCP'
How do i resolve it?

That line is not correct, please replace it with this:
sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK"); //Start connection as client

Related

I want to make esp32 beacon that work both as ibeacon and eddystone URL beacon

Here is my code in which i want to make esp32 to advertise both as ibeacon and eddystone URL. In start it will act as a Ibeacon but when i write URL text from nrf connect app after connection URL beacon function is called and advertisement data changes to URL format from setBeacon() method.
#include "sys/time.h"
#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
#include "BLEBeacon.h"
#include "esp_sleep.h"
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep 4 seconds and then wake up
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
RTC_DATA_ATTR static uint32_t bootcount;
uint16_t beconUUID = 0xFEAA;
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEAdvertising *pAdvertising;
struct timeval now;
const char turnIbeacon ='IBeacon';
const char turnURL ='URL';
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
void setBeacon2() {
Serial.println("Function2 is called");
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setManufacturerId(0x4C00); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!)
oBeacon.setProximityUUID(BLEUUID(beconUUID));
oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16);
oBeacon.setMinor(bootcount & 0xFFFF);
oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04
std::string strServiceData = "";
strServiceData += (char)26; // Len
strServiceData += (char)0xFF; // Type
strServiceData += oBeacon.getData();
oAdvertisementData.addData(strServiceData);
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->setScanResponseData(oScanResponseData);
}
void setBeacon() {
char beacon_data[22];
Serial.println("Function is called");
beacon_data[0] = 0x10; // Eddystone Frame Type (Eddystone-URL)
beacon_data[1] = 0x20; // Beacons TX power at 0m
beacon_data[2] = 0x03; // URL Scheme 'https://'
beacon_data[3] = 'y'; // URL add 1
beacon_data[4] = 'o'; // URL add 2
beacon_data[5] = 'u'; // URL add 3
beacon_data[6] = 't'; // URL add 4
beacon_data[7] = 'u'; // URL add 5
beacon_data[8] = 'b'; // URL add 6
beacon_data[9] = 'e'; // URL add 7
beacon_data[10] = '.'; // URL add 8
beacon_data[11] = 'c'; // URL add 9
beacon_data[12] = 'o'; // URL add 10
beacon_data[13] = 'm'; // URL add 11
oAdvertisementData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14));
}
class MyCallbacks: public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string value = pCharacteristic->getValue();
if (value.length() > 0)
{
Serial.println("*********");
Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
{
Serial.print(value[i]);
// if(value[i] == turnON)
// {
//setBeacon();
// }
//
/* If received Character is 0, then turn OFF the LED */
if(value[i] == turnIbeacon)
{
setBeacon();
}
}
Serial.println();
Serial.println("*********");
}
}
};
void setup()
{
Serial.begin(115200);
gettimeofday(&now, NULL);
Serial.printf("start ESP32 %d\n",bootcount++);
Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n",now.tv_sec,now.tv_sec-last);
last = now.tv_sec;
BLEDevice::init("ESP32-BLE-Server");
BLEServer *pServer = BLEDevice::createServer();
pAdvertising = BLEDevice::getAdvertising();
BLEDevice::startAdvertising();
setBeacon2();
BLEService *pService = pServer->createService(beconUUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop()
{
delay(2000);
}
In initial run i was able to write something on esp32 using nrf connect app but now that write sign is not showing. And after connect when start i re-scan my device will disappears.
Note: Everything is running perfectly when i am uploading individual code of ibeacon and eddystone url on esp32

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).

Problem Reading From Thingspeak from Arduino

I am using this code to retrieve data from a Thingspeak channel in a JSON format. I am using an ESP8266 along with an Arduino Nano 33 BLE. The Nono 33 BLE Arduino board is not compatible with Thingspeak library and it doesn’t support SoftwareSerial. Alternatively, I am using serial1 to communicate with the ESP8266 and REST API method to get the data from Thingspeak as it is shown in the code. However, I cannot get it to work. It is worth noting that Serial1.available() always gives zero even after adding delays.
I have used the same code to send data to the same Thingspeak channel and it works perfectly. I have no clue why it is not reading from the channel. I would really appreciate any help with this problem
Thanks in advance.
String AP ="xxxxxxxxxxx";
String PASS ="xxxxxxxxxxxxxx";
String PORT = "80";
String field = "Id";
int countTrueCommand;
int countTimeCommand;
boolean found = false;
String Data ="";
void setup() {
Serial.begin(9600);
Serial1.begin(115200);
sendCommand("AT",5,"OK",false);
Serial1.println("AT+UART_DEF=9600,8,1,0,0");
delay(1000);
Serial1.end();
Serial1.begin(9600);
ConnectToWifi();
}
void loop() {
String getData="GET https://api.thingspeak.com/channels/1335558/fields/1?api_key=7XFZKXEGOV5HY4TQ";
sendCommand("AT+CIPMUX=1",5,"OK",false);
sendCommand("AT+CIPSTART=4,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK",false);
sendCommand("AT+CIPSEND=4," +String(getData.length()+4),4,">",false);
sendCommand(getData,20,"OK",true);
delay(1500);
countTrueCommand++;
sendCommand("AT+CIPCLOSE=0",5,"OK",false);
}
bool ConnectToWifi(){
for (int a=0; a<15; a++)
{
sendCommand("AT",5,"OK",false);
sendCommand("AT+CWMODE=1",5,"OK",false);
boolean isConnected = sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK",false);
if(isConnected)
{
return true;
}
}
}
bool sendCommand(String command, int maxTime, char readReplay[],boolean isGetData) {
boolean result=false;
//Test Purpose
Serial.print(countTrueCommand);
Serial.print(". at command => ");
Serial.print(command);
Serial.print(" ");
while(countTimeCommand < (maxTime*1))
{
Serial1.println(command);
if(Serial1.find(readReplay))//ok
{
if(isGetData)
{
if(Serial1.find(readReplay))
{
Serial.println("Success : Request is taken from the server");
}
while(Serial1.available())
{
char character = Serial1.read()
Data.concat(character); /
if (character == '\n')
{
Serial.print("Received: ");
Serial.println(Data);
delay(50);
Data = "";
}
}
}
result = true;
break;
}
countTimeCommand++;
}
if(result == true)
{
Serial.println("Success");
countTrueCommand++;
countTimeCommand = 0;
}
if(result == false)
{
Serial.println("Fail");
countTrueCommand = 0;
countTimeCommand = 0;
}
found = false;
return result;

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.

if equals not matched but should be. Aduino IDE Serial

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");
}
}

Resources