I have been working on a project. I have two sketches. One is to get GPS location and one is send location via SMS (GSM Module). I want to combine both sketches.
GPS sketch:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
//long lat,lon; // create variable for latitude and longitude object
float flat, flon;
SoftwareSerial gpsSerial(4, 3); // create gps sensor connection
TinyGPS gps; // create gps object
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(9600); // connect gps sensor
}
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
// smartdelay(0);
}
void loop(){
while(gpsSerial.available()){ // check for gps data
if(gps.encode(gpsSerial.read())){ // encode gps data
// gps.get_position(&lat,&lon); // get latitude and longitude
gps.f_get_position(&flat, &flon);
String lat = String(flat,6);
String lon = String(flon,6);
Serial.print(lat);
Serial.print(' ');
Serial.println(lon);
}
}
}
GSM sketch:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
void setup()
{
mySerial.begin(9600); // Setting the baud rate of GSM Module
Serial.begin(9600); // Setting the baud rate of Serial Monitor (Arduino)
delay(100);
}
int index=0;
long dlat=0,dlong=0;
char st[256],st1[256],st2[256];
void RecieveMessage()
{
mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
// mySerial.println("cheking");
// mySerial.println(string);
}
void loop()
{
if (Serial.available()>0)
RecieveMessage();
if (mySerial.available()>0)
{
//int st;
st[index++] = mySerial.read();
//Serial.write(st[index-1]);
if(index>=51&&index<=63){
st1[index-51]=st[index-1];
Serial.write(st1[index-51]);
}
if(index>=65&&index<=77){
st2[index-65]=st[index-1];
Serial.write(st2[index-65]);
}
/*if(index==77)
{
int i=0;
mySerial.print(st1);
for(i=0;i<13;i++)
{
if(st1[i]!='.')
dlat=dlat*10+(st1[i]-'0');
if(st2[i]!='.')
dlong=dlong*10+(st2[i]-'0');
//Serial.print(dlat);
}
//Serial.print(dlat);
//Serial.print(" ");
//Serial.print(dlong);
*/
}
}
I want to merge these two sketches so that I can send location via GSM sketch and receive location through GPS sketch.
Any help will be appreciated.
Thanks.
The following way you can merge your two sketches :
#include <AltSoftSerial.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
//long lat,lon; // create variable for latitude and longitude object
float flat, flon;
SoftwareSerial gpsSerial(4, 3); // create gps sensor connection
TinyGPS gps; // create gps object
static const int RXPin = 8, TXPin = 9;
AltSoftSerial mySerial(RXPin, TXPin);
int index=0;
long dlat=0,dlong=0;
char st[256],st1[256],st2[256];
void RecieveMessage()
{
mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
// mySerial.println("cheking");
// mySerial.println(string);
}
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(9600); // connect gps sensor
mySerial.begin(9600); // Setting the baud rate of GSM Module
delay(100);
}
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
// smartdelay(0);
}
void loop(){
while(gpsSerial.available()){ // check for gps data
if(gps.encode(gpsSerial.read())){ // encode gps data
// gps.get_position(&lat,&lon); // get latitude and longitude
gps.f_get_position(&flat, &flon);
String lat = String(flat,6);
String lon = String(flon,6);
Serial.print(lat);
Serial.print(' ');
Serial.println(lon);
if (Serial.available()>0)
RecieveMessage();
if (mySerial.available()>0)
{
//int st;
st[index++] = mySerial.read();
//Serial.write(st[index-1]);
if(index>=51&&index<=63){
st1[index-51]=st[index-1];
Serial.write(st1[index-51]);
}
if(index>=65&&index<=77){
st2[index-65]=st[index-1];
Serial.write(st2[index-65]);
}
/*if(index==77)
{
int i=0;
mySerial.print(st1);
for(i=0;i<13;i++)
{
if(st1[i]!='.')
dlat=dlat*10+(st1[i]-'0');
if(st2[i]!='.')
dlong=dlong*10+(st2[i]-'0');
//Serial.print(dlat);
}
//Serial.print(dlat);
//Serial.print(" ");
//Serial.print(dlong);
*/
}
}
}
}
P.S : I have changed the pins for GPS and rest part is same irrespective of adding AltSoftSerial it is a library same as SoftwareSerial (Download it from manage libraries and it requires pins 8 and 9)
Related
I am having a weeny trouble with my SAMD21 board. I have got this starter kit (schematics) and I want to add some more sensors. They use SPI, so I programmed them. Since SAMD21 got the code it lag's everytime, when code reache's the sensor begin function. Please give me some advice, how to control both SPI's correctly and avoid lags.
*lags are total lags - SAMD21 do nothing after reaching the begin function.
*schematics: http://kit.sciencein.cz/wiki/images/b/be/MainBoard_v2.0_RevB_SCH.png
*sorry for mistakes in the code (it is long code cut to short)
*my code:
#include <Adafruit_BME280.h> // include Adafruit BME280 library
#include <Adafruit_INA219.h> // include INA219
#include <SD.h> // include Arduino SD library
#include "Open_Cansat_GPS.h"
//include our new sensors
#include "MQ131.h"
#include <Wire.h>
#include <SPI.h>
#include "RFM69.h" // include RFM69 library
// Local
#define PC_BAUDRATE 115200
#define MS_DELAY 0 // Number of milliseconds between data sending and LED signalization
#define LED_DELAY 100
#define Serial SerialUSB
RTCZero rtc;
// RFM69
#define NETWORKID 0 // Must be the same for all nodes (0 to 255)
#define MYNODEID 1 // My node ID (0 to 255)
#define TONODEID 2 // Destination node ID (0 to 254, 255 = broadcast)
#define FREQUENCY RF69_433MHZ // Frequency set up
#define FREQUENCYSPECIFIC 433000000 // Should be value in Hz, now 433 Mhz will be set
#define CHIP_SELECT_PIN 43 //radio chip select
#define INTERUP_PIN 9 //radio interrupt
// BME280 SETTING
#define BME280_ADDRESS_OPEN_CANSAT 0x77
#define SEALEVELPRESSURE_HPA 1013.25
//OZONE2CLICK
const byte pinSS = 2; //cs pin
const byte pinRDY = 12;
const byte pinSCK = 13;
const byte O2Pin = 10;
#define DcPin 8
// SD card
#define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)
// create object 'rf69' from the library, which will
// be used to access the library methods by a dot notation
RFM69 radio(CHIP_SELECT_PIN, INTERUP_PIN, true);
// define our own struct data type with variables; used to send data
typedef struct
{
int16_t messageId;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t sec;
float longitude;
float latitude;
uint8_t num_of_satelites;
float temperature;
float pressure;
float altitude;
float humidity_bme280;
float voltage_shunt;
float voltage_bus;
float current_mA;
float voltage_load;
int16_t rssi;
} messageOut;
messageOut cansatdata; //create the struct variable
// create object 'bme' from the library, which will
// be used to access the library methods by a dot notation
Adafruit_BME280 bme;
// create object 'ina219' from the library with address 0x40
// (according to the circuit, which will be used to access the
// library methods by a dot notation
Adafruit_INA219 ina219(0x40);
// create object 'gps' from the library
OpenCansatGPS gps;
// SD card
File file; // SD library variable
// LEDS
#define D13_led_pin 42 // D13 LED
#define M_led_pin 36 // MLED
// Local variables
int idCounter = 1;
bool isBmeOk = true;
bool isSdOk = true;
bool isRadioOk = true;
bool isGpsConnected = true;
// My variables
float NH3Data;
float COData;
float NO2Data;
float PPMO2;
float PPBO2;
float MGM3O2;
float UGM3O2;
float SSmoke1;
float SSmoke2;
float SSmoke3;
float ESmoke1;
float ESmoke2;
float ESmoke3;
int DataCounter = 0;
void OZONE2CLICKCalibrate ()
{
Serial.println("2");
//MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000); //(int _pinCS, int _pinRDY, int _pinPower, MQ131Model _model, int _RL)
Serial.println("99");
Serial.println("Calibration in progress...");
MQ131.calibrate();
Serial.println("Calibration done!");
Serial.print("R0 = ");
Serial.print(MQ131.getR0());
Serial.println(" Ohms");
Serial.print("Time to heat = ");
Serial.print(MQ131.getTimeToRead());
Serial.println(" s");
}
void OZONE2CLICKMeasure ()
{
Serial.println("Sampling...");
MQ131.sample();
Serial.print("Concentration O3 : ");
PPMO2 = MQ131.getO3(PPM);
Serial.print(PPMO2);
Serial.println(" ppm");
Serial.print("Concentration O3 : ");
PPBO2 = MQ131.getO3(PPB);
Serial.print(PPBO2);
Serial.println(" ppb");
Serial.print("Concentration O3 : ");
MGM3O2 = MQ131.getO3(MG_M3);
Serial.print(MGM3O2);
Serial.println(" mg/m3");
Serial.print("Concentration O3 : ");
UGM3O2 = MQ131.getO3(UG_M3);
Serial.print(UGM3O2);
Serial.println(" ug/m3");
}
void setup()
{
pinMode(pinSS, OUTPUT);
digitalWrite(pinSS, HIGH);
delay(10000);
Serial.begin(PC_BAUDRATE);
// wait for the Arduino serial (on your PC) to connect
// please, open the Arduino serial console (right top corner)
// note that the port may change after uploading the sketch
// COMMENT OUT FOR USAGE WITHOUT A PC!
// while(!Serial);
Serial.println("openCanSat PRO");
Serial.print("Node ");
Serial.print(MYNODEID,DEC);
Serial.println(" ready");
// begin communication with the BME280 on the previously specified address
// print an error to the serial in case the sensor is not found
if (!bme.begin(BME280_ADDRESS_OPEN_CANSAT))
{
isBmeOk = false;
Serial.println("Could not find a valid BME280 sensor, check wiring!");
return;
}
// begin communication with the INA219
ina219.begin();
// check of Gps is connected
Wire.beginTransmission(0x42); // 42 is addres of GPS
int error = Wire.endTransmission();
if (error != 0)
{
isGpsConnected = false;
}
// begin communication with gps
gps.begin();
// Uncomment when you want to see debug prints from GPS library
// gps.debugPrintOn(57600);
if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
{
isRadioOk = false;
Serial.println("RFM69HW initialization failed!");
}
else
{
radio.setFrequency(FREQUENCYSPECIFIC);
radio.setHighPower(true); // Always use this for RFM69HW
}
pinMode(D13_led_pin, OUTPUT);
pinMode(DcPin, OUTPUT);
pinMode(MICS6814Pin, OUTPUT);
pinMode(MICSVZ89TEPin, OUTPUT);
pinMode(O2Pin, OUTPUT);
GyroscopeTurnOn();
}
void loop()
{
cansatdata.messageId = idCounter;
GyroscopeMeasure();
LandingChecker();
Serial.println("MessageId = " + static_cast<String>(cansatdata.messageId));
cansatdata.temperature = 0;
cansatdata.pressure = 0;
cansatdata.altitude = 0;
if(isBmeOk)
{
cansatdata.temperature += bme.readTemperature();
cansatdata.pressure += bme.readPressure() / 100.0F;
cansatdata.altitude += bme.readAltitude(SEALEVELPRESSURE_HPA);
cansatdata.humidity_bme280 = bme.readHumidity();
}
Serial.println("Temperature = " + static_cast<String>(cansatdata.temperature) + " *C");
Serial.println("Pressure = " + static_cast<String>(cansatdata.pressure) + " Pa");
Serial.println("Approx altitude = " + static_cast<String>(cansatdata.altitude) + " m");
Serial.println("Humidity = " + static_cast<String>(cansatdata.humidity_bme280) + " %");
// read values from INA219 into structure
cansatdata.voltage_shunt = ina219.getShuntVoltage_mV();
cansatdata.voltage_bus = ina219.getBusVoltage_V();
cansatdata.current_mA = ina219.getCurrent_mA();
cansatdata.voltage_load = cansatdata.voltage_bus + (cansatdata.voltage_shunt / 1000);
Serial.println("Shunt Voltage: " + static_cast<String>(cansatdata.voltage_shunt) + " mV");
Serial.println("Bus Voltage: " + static_cast<String>(cansatdata.voltage_bus) + " V");
Serial.println("Current: " + static_cast<String>(cansatdata.current_mA) + " mA");
Serial.println("Load Voltage: " + static_cast<String>(cansatdata.voltage_load) + " V");
// Initialize GPS
cansatdata.year = 0;
cansatdata.month = 0 ;
cansatdata.day = 0;
cansatdata.hour = 0;
cansatdata.minute = 0;
cansatdata.sec = 0;
cansatdata.latitude = 0;
cansatdata.longitude = 0;
cansatdata.num_of_satelites = 0;
// save start time in millisec
uint32_t start = millis();
// END LED BLINK
digitalWrite(D13_led_pin, LOW);
pinMode(M_led_pin, INPUT);
// END LED BLINK
if(isGpsConnected)
{
if (gps.scan(250))
{
cansatdata.year = gps.getYear();
cansatdata.month = gps.getMonth();
cansatdata.day = gps.getDay();
cansatdata.hour = gps.getHour();
cansatdata.minute = gps.getMinute();
cansatdata.sec = gps.getSecond();
cansatdata.latitude = gps.getLat();
cansatdata.longitude = gps.getLon();
cansatdata.num_of_satelites = gps.getNumberOfSatellites();
Serial.println(String("Time to find fix: ") + (millis() - start) + String("ms"));
Serial.println(String("Datetime: ") + String(cansatdata.year) + "/"+ String(cansatdata.month) + "/"+ String(cansatdata.day) + " " + String(cansatdata.hour) + ":"+ String(cansatdata.minute) + ":"+ String(cansatdata.sec));
Serial.println(String("Lat: ") + String(cansatdata.latitude, 7));
Serial.println(String("Lon: ") + String(cansatdata.longitude, 7));
Serial.println(String("Num of sats: ") + String(cansatdata.num_of_satelites));
Serial.println();
}
else
{
Serial.println("Gps have no satelit to fix.");
}
}
// RFM69HW
cansatdata.rssi = 0;
if(isRadioOk)
{
cansatdata.rssi = radio.RSSI;
Serial.println("Signal = " + static_cast<String>(radio.RSSI));
radio.send(TONODEID, (const void*)&cansatdata, sizeof(cansatdata));
}
Serial.println();
// START LED hart beat
pinMode(M_led_pin, OUTPUT);
digitalWrite(D13_led_pin, HIGH);
digitalWrite(M_led_pin, HIGH);
// START LED hart beat
if(!isGpsConnected)
{
delay(200);
}
idCounter ++;
}
I am working on a project and I encountered some problems.
I am using a DHT11 temperature sensor, an Arduino Uno and a TFT LCD display 2.2-inch model ITDB02-2.2.
What I want my project to do is to use 2 functioning modes for the sensor that I can select from the keyboard at the beginning of the program(one which is normal and one which will be used on special occasions)(so I need serial communication).
I noticed that the screen does not function if I start a serial communication at any rate so I used Arduino Serial.begin(9600) and Serial.end() for the mode selecting part of the program.
THE PROBLEM: My Arduino is still sending data through serial port even if I ended the serial communication and is looking like this:
I found out that Serial.end() function does not shut off serial communication but just the rate of communication. I am curious if you have any idea that I can use in order to get rid of the extra data, to neglect it before the computer receives it.
I`m stuck. I thought that interruptions would be a solution but they are not as far as I researched on the internet.
My ARDUINO CODE:
#include <SimpleDHT.h>
#include <UTFT.h>
UTFT myGLCD(ITDB22,A5,A4,A3,A2);
SimpleDHT11 dht11;
// Declare which fonts we will be using
extern uint8_t BigFont[];
//dht sensor data pin
int dataPinSensor1 = 12;
char mode;
int del;
void setup()
{
Serial.begin(9600);
Serial.print("Select functioning mode");
mode=SensorModeSelect(mode);
Serial.end();
pinMode(12, INPUT);
}
void loop()
{
if(mode=='1') {
FirstFuncMode(dataPinSensor1);
}
if(mode=='2') {
SecondFuncMode(dataPinSensor1,del);
}
delay(10);
}
char SensorModeSelect(char in)
{
char mode='0';
while(mode=='0') {
if(Serial.available() > 0) {
mode=Serial.read();
}
}
if (mode == '1') {
Serial.print("\nMOD1 SELECTED: press t key to aquire data \n");
}
if (mode == '2') {
Serial.print("\nMOD2 SELECTED: press q if you want to quit auto mode \n");
Serial.print("Select the data aquisition period(not smaller than 1 second) \n");
}
return mode;
}
int DataAqPeriod()
{
int del=0;
while(del==0) {
while(Serial.available() > 0) {
//Get char and convert to int
char a = Serial.read();
int c = a-48;
del *= 10;
del += c;
delay(10);
}
}
del*=1000;
return del;
}
void FirstFuncMode(int dataPinSensor1)
{
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
bool DispCond=false;
Serial.begin(9600);
delay(1500);
if (Serial.read() == 't' ) {
DispCond=true;
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode");
}
byte f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(1500);
}
Serial.end();
if(DispCond==true) {
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
//print value on LCD
displayNoInit((int)temperature,(int)humidity);
}
}
void SecondFuncMode(int dataPinSensor1,int del)
{
bool q=false;
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
Serial.begin(9600);
del=DataAqPeriod();
Serial.end();
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
while(q==false) {
Serial.begin(9600);
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode \n");
}
float f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(del);
if(Serial.read() == 'q')
q=true;
Serial.end();
displayNoInit((int)temperature,(int)humidity);
delay(10);
}
}
void displayNoInit(int temperature,int humidity)
{
//effective data display
myGLCD.clrScr();
myGLCD.setColor(255, 255, 0);
myGLCD.setBackColor(10,10,10);
myGLCD.print(" Temperature ", CENTER, 10);
myGLCD.setColor(254, 254, 254);
myGLCD.printNumI(temperature, CENTER, 45);
myGLCD.setColor(255, 255, 0);
myGLCD.print("C ", RIGHT, 45);
myGLCD.print("Relative Hum.", CENTER, 90);
myGLCD.setColor(204, 245, 250);
myGLCD.printNumI(humidity, CENTER, 120);
myGLCD.print("%", RIGHT, 120);
}
You are correct in the definition that Serial.end() does not disable the serial monitor, only the interrupts. After calling Serial.end() you can disable the serial monitor like so.
#include <avr/io.h>
// Save status register, disable interrupts
uint8_t oldSREG = SREG;
cli();
// Disable TX and RX
cbi(UCSRB, RXEN);
cbi(UCSRB, TXEN);
// Disable RX ISR
cbi(UCSRB, RXCIE);
// Flush the internal buffer
Serial.flush();
// Restore status register
SREG = oldSREG;
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
}
}
I have an arduino sodaq with a MIcrochip LoRabee attached, as well as a GPS module. I am trying to use SoftwareSerial to read the GPS data but it won't recognise it!
The sketch was previously working on a Chinese cloned Nano and I was able to read the data fine. I've changed the ports to 4 and 5 (I was using 3 and 4 on the Chinese Nano) but other than that the code is identical.
Any ideas?
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
This sample code 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 = 2, TXPin = 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("FullExample.ino"));
Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
}
void loop()
{
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printDateTime(gps.date, gps.time);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);
unsigned long distanceKmToLondon =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON);
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
Serial.println();
smartDelay(1000);
if (millis() > 5000 && gps.charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartDelay(0);
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartDelay(0);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
Serial.print(F("********** "));
}
else
{
char sz[32];
sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
Serial.print(sz);
}
if (!t.isValid())
{
Serial.print(F("******** "));
}
else
{
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(0);
}
static void printStr(const char *str, int len)
{
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartDelay(0);
}
Sodaq wrote their own softwareserial library. If you install that library, it should resolve your issues:
You can find it here.
But it doesn't work. I tried it.
But u can use this.
Hardware Serials
The SODAQ ONE has 3 hardware serials:
SerialUSB – This is for when you are debugging over the USB Cable.
Serial – Serial is attached to pin D12/A12/TX and D13/A12/RX.
Serial1 – Is connected to the RN2483 LoRaWAN Module.
Serial is connected to pin 12 and 13
SerialUSB is for debugging over the usb cable
Instead of SoftwareSerial ss(RXPin, TXPin); you could add:
#define ss Serial
All your code with Serial must be SerialUSB
And then something else. Are u still using a gps module or is this a gns? If so you can try neogps. Here is an example for the sodaq explorer.
https://github.com/Kaasfabriek/Junior_Internet_of_Things_2018/blob/master/test_NMEAloc/test_NMEAloc.ino
For the sodaq explorer u might need a hack if u will use neogps like this.
https://github.com/Kaasfabriek/Junior_Internet_of_Things_2018/tree/master/hack
Neogps can be found here. I see u are using tinygps, if u have a gps that talks gps dialect that will work. If u have a gns it won't.
https://github.com/SlashDevin/NeoGPS
I'm creating a RFID logger with Arduino. I connected a RFID scanner, RTC module and a SD card reader. All parts are working fine together but when i started combining different sketches a problem occured.
Reading files and writing to files on the SD card is no problem as long as i don't scan a RFID card. When input is received from the RFID scanner it is no longer possible to read or write to the sd card. The connection seems to be "disconnected" as soon as RFID input is received.
I tried using different pins for the RFID scanner, another sequence of initializing in the setup but it doesn't make a difference.
Is this a limitation of the Arduino or am I doing something wrong?
I'm using a ATS125KRW RFID shield and a Catalex MicroSD card adpater in combination with a Arduino Mega.
// SD
#include <SD.h>
File myFile;
char idArray[100][11];
char nameArray[100][11];
// RTC
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
// RFID
#include <SoftwareSerial.h>
SoftwareSerial rfid = SoftwareSerial(A8 , A9); //(RX,TX)
String cardID; //string to store card id
char c;
char cardArray[11];
int incomingByte = 0; // for incoming serial data
String rfidInput;
boolean logtosd;
void setup()
{
Serial.begin(9600);
initializeRFID();
initializeSD();
initializeRTC();
readfromSD();
}
void loop()
{
while(rfid.available()>0)
{
c = rfid.read();
rfidInput += c;
}
if(rfidInput.length() >=12)
{
Serial.print("SCanned: ");
Serial.println(rfidInput);
//writetoSD(rfidInput);
writetoSD("kaart");
rfidInput = "";
}
while(Serial.available()>0)
{
c = Serial.read();
cardID += c;
}
if(cardID.length() >= 2)
{
writetoSD(cardID);
cardID = "";
}
}
void initializeSD()
{
// GND en VCC aansluiting via pin 48 en 49
pinMode(48, OUTPUT); // set pin to output
digitalWrite(48, LOW); // GND pin dus LOW
pinMode(49, OUTPUT); // set pin to output
digitalWrite(49, HIGH); // VCC pin dus HIGH
pinMode(53, OUTPUT);
if (!SD.begin(53))
{
Serial.println("SD initialization failed");
return;
}
Serial.println("SD initialized");
}
void readfromSD()
{
//open the file for reading:
myFile = SD.open("db.txt");
if (myFile)
{
char line[25]; //Array to store entire line
int linenumber = 0;
int arrayPlace = 0;
while (myFile.available())
{
char ch = myFile.read();
if(ch != '\n')
{
line[arrayPlace] = ch;
arrayPlace ++;
}
else
{
char id[11];
char name[11];
//get ID from entire line
for(int x = 0; x <= 10 ; x++)
{
id[x] = line[x];
}
//Get NAME from entire line
for(int x = 11; x <= 19 ; x++)
{
if (line[x] != ';')
{
name[x-11] = line[x];
}
else
{
// NULL TERMINATE THE ARRAY
name[x-11] = '\0';
//STOP
x = 20;
}
}
// save name to nameArray
for(int x = 0; x <= 11 ; x++)
{
nameArray[linenumber][x] = name[x];
}
// NULL TERMINATE THE ARRAY
id[10] = '\0';
// save id to idArray
for(int x = 0; x <= 11 ; x++)
{
idArray[linenumber][x] = id[x];
}
linenumber +=1;
arrayPlace = 0;
} //else
} //while
// close the file:
myFile.close();
}
else
{
// if the file didn't open, print an error:
Serial.println("error opening db.txt");
}
}
void writetoSD(String cardID)
{
//open file for writing
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile)
{
Serial.println("Writing time to test.txt...");
DateTime now = rtc.now();
myFile.print(now.day(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.year(), DEC);
myFile.print(' ');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print('\t');
Serial.println("Writing string to test.txt...");
myFile.println(cardID);
// close the file:
myFile.flush();
Serial.println("done.");
}
else
{
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void initializeRTC()
{
// GND en VCC aansluiting via pin 18 en 19
pinMode(18, OUTPUT); // set pin to output
digitalWrite(18, LOW); // GND pin dus LOW
pinMode(19, OUTPUT); // set pin to output
digitalWrite(19, HIGH); // VCC pin dus HIGH
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin();
Serial.print("RTC Initialized: ");
DateTime now = rtc.now();
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void initializeRFID()
{
rfid.begin(9600);
Serial.println("RFID initialized");
}
I think you are running out of RAM ,i have done a lot of data logging on SD card with Arduino and its a very resources taking job for the minial 2kb ram on the UNO (assuming u using UNO).
Try using MemoryFree() library before every place you see there might be problem to see if you are running outta memory?