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

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

Related

How to send Bluetooth data from ESP32 in arduino?

Easy to handle received data with BLE but can't send data.
I'm using ESP32 BLE Uart code.
It's easy to get data from RxCharateristic but I don't know how to send data.
I'm trying to use TxCharacteristic to send data with BLE.
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++){
Serial.print(rxValue[i]);
}
}
}
};
void setup() {
Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("TheOneSystem");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
if (deviceConnected) {
pTxCharacteristic->setValue(&txValue, 1);
pTxCharacteristic->notify();
txValue++;
delay(10); // bluetooth stack will go into congestion, if too many packets are sent
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}
I can easily handle received data with this part of code
class MyCallbacks: public BLECharacteristicCallbacks {
String bleData;
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++){
//Serial.print(rxValue[i]);
bleData=bleData+rxValue[i];
}
Serial.println();
Serial.println(bleData);
Serial.println("*********");
int first = bleData.indexOf(",");
String bleSSID = bleData.substring(0, first);
String blepw = bleData.substring(first+1, bleData.length());
Serial.println("Wifi : " + bleSSID + "," + "Password : " + blepw);
bleData="";
}
}
};
How to send data by using TxCharacteristic?
In my receiving code, I'm using this function to use callback.
if(pTxCharacteristic->canNotify()) {
pTxCharacteristic->registerForNotify(notifyCallback);
}
And here is my notifyCallback function i got from Google.
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify){
Serial.println(data);
}
It seems like i have to add a little function in notifyCallback.
However errors continue to occur. I can't get data. Tnx for help.

ESP32 Scan for BLE devices with in mesh network

I'm working on a project where I have 3 esp32s in a mesh network that each scans for a 4th to 5th esp32 that inst in the mesh network to get the RSSI of the BLE advertisement.
I made code where I'm doing these 2 parts separately but then I try to merge them it doesn't work.
Could it be that its not possible to scan for a BLE advertisement while in a Mesh network?
Updated with Source code:
#include "painlessMesh.h"
#define MESH_PREFIX "cowFarmMeshNetwork"
#define MESH_PASSWORD "cowFarmMeshNetwork"
#define MESH_PORT 5555
#define COW1_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d"
#define COW2_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4e"
#define DEVICE_NAME "Device2"
String cowRssi = "";
String CowUUID = "";
Scheduler userScheduler; // to control your personal task
painlessMesh mesh;
// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain
Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );
void sendMessage() {
String msg = "";
String testS= ",";
if(CowUUID == COW1_UUID){
String cow = "cow1";
msg = DEVICE_NAME + testS + cow + testS + cowRssi;
} else if(CowUUID == COW2_UUID){
String cow = "cow2";
msg = DEVICE_NAME + testS + cow + testS + cowRssi;
}
mesh.sendBroadcast( msg );
taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}
// Needed for painless library
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}
void newConnectionCallback(uint32_t nodeId) {
Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}
void changedConnectionCallback() {
Serial.printf("Changed connections\n");
}
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <BLEEddystoneURL.h>
#include <BLEEddystoneTLM.h>
#include <BLEBeacon.h>
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
int scanTime = 5; //In seconds
BLEScan *pBLEScan;
String strDistance = "";
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice)
{
if (advertisedDevice.haveManufacturerData() == true)
{
std::string strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00)
{
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
String beacon = oBeacon.getProximityUUID().toString().c_str();;
if( beacon == "8ec76ea3-6668-48da-9866-75be8bc86f4d" || beacon == "8ec76ea3-6668-48da-9866-75be8bc86f4e"){
Serial.println("inside");
CowUUID = beacon;
cowRssi = String(advertisedDevice.getRSSI());
}
}
}
return;
}
};
void setup() {
Serial.begin(115200);
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP ); // set before init() so that you can see startup messages
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT );
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
userScheduler.addTask( taskSendMessage );
taskSendMessage.enable();
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(60000);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
// it will run the user scheduler as well
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
mesh.update();
}

C++ how to query value outside the callback arduino

I want that the measurement interval and MQTT server settings can be changed from cellphone by BLE. I use LightBlue as a mobile application.
Here is my BLE code that works well with my mobile application
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
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]);
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
Serial.println("1- Download and install an BLE scanner app in your phone");
Serial.println("2- Scan for BLE devices in the app");
Serial.println("3- Connect to MyESP32");
Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");
Serial.println("5- See the magic =)");
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// put your main code here, to run repeatedly:
delay(2000);
}
This is MQTT code :
void loop() {
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
// New DHT sensor readings
hum = dht.readHumidity();
// Read temperature as Celsius (the default)
temp = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//temp = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(temp) || isnan(hum)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Publish an MQTT message on topic esp32/dht/temperature
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_PUB_TEMP, packetIdPub1);
Serial.printf("Message: %.2f \n", temp);
// Publish an MQTT message on topic esp32/dht/humidity
uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(hum).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_PUB_HUM, packetIdPub2);
Serial.printf("Message: %.2f \n", hum);
}
}
Please how I can set the interval to whichever variable from the BLE code instead of 10000.
long interval = 10000;
You need to declare your variable interval as global variable to access it from everywhere in your file. A global variable can be declared outside of functions.
The value you receive is of type std::string and you want to use it as long. You can use toInt() to convert the variable from String to Long.
Try something like this:
long interval = 10000; // Set default value
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]);
Serial.println();
Serial.println("*********");
interval = value.toInt(); // <-- Set received value
}
}
};

integrating the AdafruitFona GSM shield with tiny gps library

i need help in integrating the two libraries so that i can send the GPS data via GSM . Information regarding the use of two special Serial is needed and also a help with the code is needed .
The below segmnet containts the code for the GPS shield this has to be used to generate the location and this data has to be sent via gsm to a mobile number.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;//was 4 and 3;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
Serial.println(F("GPS GSM tracking system"));
Serial.println(F("Sabdadon Presents"));
Serial.print(F("Search and Rescue")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("Sabarish"));
Serial.println();
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0)
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 500000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}
}
void displayInfo()
{
delay(10000);
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 5);
Serial.print(F(","));
Serial.print(gps.location.lng(), 5);
// latitude=gps.location.lat();
//longitude=gps.location.lng();
//if(latitude && longitude)
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
}
else
{
ss.read();
Serial.print(F("INVALID"));
}
Serial.println();
}
FOR GSM
#include "Adafruit_FONA.h"
#define FONA_RX 2//2
#define FONA_TX 3//3
#define FONA_RST 4//4
char replybuffer[255];
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
uint8_t type;
void setup()
{
while (!Serial);
Serial.begin(115200);
Serial.println(F("FONA basic test"));
Serial.println(F("Initializing....(May take 3 seconds)"));
fonaSerial->begin(4800);
if (! fona.begin(*fonaSerial)) {
Serial.println(F("Couldn't find FONA"));
while (1);
}
type = fona.type();
Serial.println(F("FONA is OK"));
Serial.print(F("Found "));
switch (type) {
case FONA800L:
Serial.println(F("FONA 800L")); break;
case FONA800H:
Serial.println(F("FONA 800H")); break;
case FONA808_V1:
Serial.println(F("FONA 808 (v1)")); break;
case FONA808_V2:
Serial.println(F("FONA 808 (v2)")); break;
case FONA3G_A:
Serial.println(F("FONA 3G (American)")); break;
case FONA3G_E:
Serial.println(F("FONA 3G (European)")); break;
default:
Serial.println(F("???")); break;
}
// Print module IMEI number.
char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
uint8_t imeiLen = fona.getIMEI(imei);
if (imeiLen > 0) {
Serial.print("Module IMEI: "); Serial.println(imei);
}
}
void loop()
{ Serial.print(F("FONA> "));
while (! Serial.available() ) {
if (fona.available()) {
Serial.write(fona.read());
}
}
// send an SMS!
char sendto[21], message[141];
flushSerial();
Serial.print(F("Send to #"));
readline(sendto, 20);
Serial.println(sendto);
Serial.print(F("Type out one-line message (140 char): "));
readline(message, 140);
Serial.println(message);
if (!fona.sendSMS(sendto, message)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("Sent!"));
}
}
void flushSerial() {
while (Serial.available())
Serial.read();
}
char readBlocking() {
while (!Serial.available());
return Serial.read();
}
uint16_t readnumber() {
uint16_t x = 0;
char c;
while (! isdigit(c = readBlocking())) {
//Serial.print(c);
}
Serial.print(c);
x = c - '0';
while (isdigit(c = readBlocking())) {
Serial.print(c);
x *= 10;
x += c - '0';
}
return x;
}
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
uint16_t buffidx = 0;
boolean timeoutvalid = true;
if (timeout == 0) timeoutvalid = false;
while (true) {
if (buffidx > maxbuff) {
//Serial.println(F("SPACE"));
break;
}
while (Serial.available()) {
char c = Serial.read();
//Serial.print(c, HEX); Serial.print("#"); Serial.println(c);
if (c == '\r') continue;
if (c == 0xA) {
if (buffidx == 0) // the first 0x0A is ignored
continue;
timeout = 0; // the second 0x0A is the end of the line
timeoutvalid = true;
break;
}
buff[buffidx] = c;
buffidx++;
}
if (timeoutvalid && timeout == 0) {
//Serial.println(F("TIMEOUT"));
break;
}
delay(1);
}
buff[buffidx] = 0; // null term
return buffidx;
}
Here is a step-by-step to mix your GPS input device and your GSM output device.
Remainder for Arduino principles:
The void setup() function is performed one time after startup.
The void loop() function is performed periodically after the
setup().
Step1 - declaration of GPS device and Serial link
// GPS and Serial link
static const int RXPin = 4, TXPin = 3;//was 4 and 3;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus DeviceGPS;
// The serial connection to the GPS device
SoftwareSerial SerialGPS(RXPin, TXPin);
Step2 - declaration of GSM/FONA device and Serial link
Including the SendTo SMS number !!!
#define FONA_RX 2//2
#define FONA_TX 3//3
#define FONA_RST 4//4
// The serial connection to the GSM device
SoftwareSerial SerialFONA = SoftwareSerial(FONA_TX, FONA_RX);
// The FONA/GSM Cellular Module device
Adafruit_FONA DeviceFONA = Adafruit_FONA(FONA_RST);
// The destination SMS number
static const char *sSendTo = "<NUMBER>";
Step3 - setup() function for (Console, GPS and GSM)
It is possible to add some extra Init.
// only execute once
void setup()
{
// Wait and Init Console
while (!Serial); // Serial over USB
Serial.begin(115200);
// Init GPS link
SerialGPS.begin(GPSBaud);
Serial.print(F("TinyGPSPlus ver: "));
Serial.println(TinyGPSPlus::libraryVersion());
// Init GSM link
SerialFONA.begin(4800);
if (! DeviceFONA.begin(SerialFONA)) {
Serial.println(F("Couldn't find FONA"));
while (1); // Stop working
}
// Add some extra Init
}
Step4 - loop() function to wait GPS location and send SMS
It is possible to use String() to create the SMS based on the
acquired DeviceGPS.location.lng() and DeviceGPS.location.lat().
// executed periodicaly
void loop()
{
// check until GPS message
while (SerialGPS.available() > 0) {
// get for a complete GPS message
DeviceGPS.encode(SerialGPS.read());
}
// flush GSM serial link
while (SerialFONA.available() > 0) {
if (DeviceFONA.available()) {
DeviceFONA.flush();
}
}
// send an SMS!
char sendto[21], message[141];
// Wait for location (lng, lat, alt) is OK
if (DeviceGPS.location.isValid()) {
// ==> create SMS with longitude & latitude
}
}

the IF command cant continue to else for turn off motor dc

I’ve a project for control a robot in arduino via android.
the trouble is when I press a button for pin 6 (Maju), its turn ON.
But when I press it again its always ON, cant turn OFF.
Here's my code:
int kananMaju;
int kiriMundur;
int kananMundur;
int kiriMaju;
#define Kanan A4
#define Kiri 13
#define Maju 6
#define Mundur A5
#define STBY 12
#define PWMA 11 //left
#define PWMB 10 //right
#define AIN2 8
#define AIN1 7
#define BIN1 3
#define BIN2 2
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(4,5); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
// This means that you need to connect the TX line from the esp to the Arduino's pin 2
// and the RX line from the esp to the Arduino's pin 3
void setup()
{
Serial.begin(9600);
esp8266.begin(9600); // your esp's baud rate might be different
pinMode(STBY,OUTPUT);
pinMode(BIN2,OUTPUT);
pinMode(BIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(AIN1,OUTPUT);
pinMode(PWMB,OUTPUT);
pinMode(PWMA,OUTPUT);
digitalWrite(STBY, HIGH); //standby
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
analogWrite(PWMB, 100); //490 Hz
analogWrite(PWMA, 100); //490 Hz
pinMode(Maju,OUTPUT);
digitalWrite(Maju,LOW);
sendCommand("AT+RST\r\n",2000,DEBUG); // reset module
sendCommand("AT+CWMODE=1\r\n",1000,DEBUG); // configure as access point
sendCommand("AT+CWJAP=\"PanduGanteng\",\"akhirpekan666\"\r\n",3000,DEBUG);
delay(10000);
sendCommand("AT+CIFSR\r\n",1000,DEBUG); // get ip address
sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
sendCommand("AT+CIPSERVER=1,8080\r\n",1000,DEBUG); // turn on server on port 80
Serial.println("Server Ready");
}
void loop()
{
if(esp8266.available()) // check if the esp is sending a message
{
if(esp8266.find("+IPD,"))
{
delay(1000); // wait for the serial buffer to fill up (read all the serial data)
// get the connection id so that we can then disconnect
int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
// the ASCII decimal value and 0 (the first decimal number) starts at 48
esp8266.find("pin="); // advance cursor to "pin="
int pinNumber = (esp8266.read()-48); // get first number i.e. if the pin 13 then the 1st number is 1
int secondNumber = (esp8266.read()-48);
if(secondNumber>=0 && secondNumber<=9)
{
pinNumber*=10;
pinNumber +=secondNumber; // get second number, i.e. if the pin number is 13 then the 2nd number is 3, then add to the first number
}
digitalWrite(pinNumber, !digitalRead(pinNumber)); // toggle pin
// build string that is send back to device that is requesting pin toggle
String content;
content = "Pin ";
content += pinNumber;
content += " is ";
if(digitalRead(Maju))
{
content += "ON";
kiriMaju;{
digitalWrite(STBY,HIGH);
analogWrite(PWMA, 100);
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
}
kananMaju;{
digitalWrite(STBY,HIGH);
analogWrite(PWMB, 100);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
}
}
else
{
content += "OFF";
}
sendHTTPResponse(connectionId,content);
// make close command
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendCommand(closeCommand,1000,DEBUG); // close connection
}
}
}
/*
* Name: sendData
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
int dataSize = command.length();
char data[dataSize];
command.toCharArray(data,dataSize);
esp8266.write(data,dataSize); // send the read character to the esp8266
if(debug)
{
Serial.println("\r\n====== HTTP Response From Arduino ======");
Serial.write(data,dataSize);
Serial.println("\r\n========================================");
}
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
/*
* Name: sendHTTPResponse
* Description: Function that sends HTTP 200, HTML UTF-8 response
*/
void sendHTTPResponse(int connectionId, String content)
{
// build HTTP response
String httpResponse;
String httpHeader;
// HTTP Header
httpHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n";
httpHeader += "Content-Length: ";
httpHeader += content.length();
httpHeader += "\r\n";
httpHeader +="Connection: close\r\n\r\n";
httpResponse = httpHeader + content + " "; // There is a bug in this code: the last character of "content" is not sent, I cheated by adding this extra space
sendCIPData(connectionId,httpResponse);
}
/*
* Name: sendCIPDATA
* Description: sends a CIPSEND=<connectionId>,<data> command
*
*/
void sendCIPData(int connectionId, String data)
{
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=data.length();
cipSend +="\r\n";
sendCommand(cipSend,1000,DEBUG);
sendData(data,1000,DEBUG);
}
/*
* Name: sendCommand
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendCommand(String command, const int timeout, boolean debug)
{
String response = "";
esp8266.print(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
I want to when I press button for pin 6 is ON, and when I press it again its OFF. But it's always turned ON, where's my fault?
Maju should be an input not an output
And you need to toggle a state
pinMode(Maju,INPUT);
static boolean function get_state()
{
static boolean previous = LOW;
static boolean state = LOW;
boolean current = digitalRead(Maju);
if (current == HIGH && current != previous) {
state = (state == LOW) ? HIGH : LOW;
}
previous = current;
return state;
}

Resources