RFID (SoftwareSerial) influences/breaks connection with SD (SPI) - arduino

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?

Related

Can I temporarily disable Arduino Serial data receive?

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;

Sending GPS location via GSM module

I am using a SIM900A GSM module and a NEO-6m GPS module. I want to send the location via the GSM module when the GSM module receives a message.
My code is working when I am receiving and sending any message with the help of the GSM module, but it is not working when I join the two, i.e. GPS and GSM modules.
Here is my code for the two.
#include <SoftwareSerial.h>
// GPS
#include <TinyGPS.h>
// GSM
SoftwareSerial SIM900A(9, 10);
SoftwareSerial mySerial(5, 6);
TinyGPS gps;
void setup() {
Serial.begin(9600);
SIM900A.begin(9600);
SIM900A.println("AT+CNMI=2,2,0,0,0");
mySerial.begin(9600);
delay(1000);
}
void loop() {
bool newdata = false;
String buffer = readSIM900A();
if(SIM900A.available() > 0)
Serial.println(SIM900A.read());
if (buffer.startsWith("\r\n+CMT: ")) {
// printing the number
Serial.println(buffer.substring(9, 22));
// Remove first 51 characters
// buffer.remove(0, 51);
int len = buffer.length();
// printing message
Serial.println(buffer.substring(51, len-2));
if (buffer.substring(51, len-2) == "location") {
Serial.println("Sending location");
// GPS
if (mySerial.available()) {
char c = mySerial.read();
if (gps.encode(c)) {
newdata = true;
}
}
if (newdata) {
long int lat, lon;
unsigned long age, age1, date, time, chars;
gps.get_position(&lat, &lon, &age);
gps.get_datetime(&date, &time, &age);
Serial.print("Lat/Long(10^-5 deg): ");
Serial.print(lat);
Serial.print(", ");
Serial.print(lon);
Serial.print(" Fix age: ");
Serial.print(age); Serial.println("ms.");
Serial.print("Date(ddmmyy): "); Serial.print(date);
Serial.print(" Time(hhmmsscc): ");
Serial.print(time);
Serial.print(" Fix age: "); Serial.print(age);
Serial.println("ms.");
Serial.print("Alt(cm): "); Serial.print(gps.altitude());
Serial.print(" Speed(mps): "); Serial.print(gps.f_speed_mps());
// setting GSM module
SIM900A.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
delay(1000); // Delay of 1000 milli seconds or 1 second
// sending location from which code word had come
SIM900A.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
// Replace x with mobile number
Serial.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
delay(1000);
SIM900A.print("Lat/Long(10^-5 deg): ");
SIM900A.print(lat);
SIM900A.print(", ");
SIM900A.print(lon);
SIM900A.print(" Fix age: ");
SIM900A.print(age); SIM900A.println("ms.");
SIM900A.print("Date(ddmmyy): "); SIM900A.print(date);
SIM900A.print(" Time(hhmmsscc): ");
SIM900A.print(time);
SIM900A.print(" Fix age: "); SIM900A.print(age);
SIM900A.println("ms.");
SIM900A.print("Alt(cm): "); SIM900A.print(gps.altitude());
SIM900A.print(" Speed(mps): "); SIM900A.print(gps.f_speed_mps());
SIM900A.println((char)26);// ASCII code of CTRL+Z
delay(1000);
}
}
}
delay(100);
}
String readSIM900A() {
String buffer;
while (SIM900A.available()) {
char c = SIM900A.read();
buffer.concat(c);
delay(10);
}
return buffer;
}
Above is my final code when the GPS and GSM modules are handled together. They are working totally fine when they are handled separately.
Connections:
Connected Tx, Rx pin of SIM900A to 9, 10 of Arduino Nano respectively, and Tx, Rx of GPS module to 5, 6 respectively. And I also made ground common with Arduino.
#include <NeoSWSerial.h>
//#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
// GPS
#include <TinyGPS.h>
// GSM
static const int RXPin = 8, TXPin = 9;
AltSoftSerial SIM900A(RXPin, TXPin);
NeoSWSerial mySerial(5, 6);
TinyGPS gps;
void setup()
{
Serial.begin(9600);
SIM900A.begin(9600);
SIM900A.println("AT+CNMI=2,2,0,0,0");
mySerial.begin(9600);
delay(1000);
}
void loop()
{
bool newdata = false;
String buffer = readSIM900A();
if(SIM900A.available() > 0)
Serial.println(SIM900A.read());
if (buffer.startsWith("\r\n+CMT: "))
{
// printing the number
Serial.println(buffer.substring(9, 22));
// Remove first 51 characters
// buffer.remove(0, 51);
int len = buffer.length();
// Remove \r\n from tail
// buffer.remove(len - 2, 2);
// printing message
Serial.println(buffer.substring(51, len-2));
if (buffer.substring(51, len-2) == "location")
{
Serial.println("Sending location");
// GPS
if (mySerial.available())
{
char c = mySerial.read();
if (gps.encode(c))
{
newdata = true;
}
}
if (newdata)
{
long int lat, lon;
unsigned long age, age1, date, time, chars;
gps.get_position(&lat, &lon, &age);
gps.get_datetime(&date, &time, &age);
Serial.print("Lat/Long(10^-5 deg): ");
Serial.print(lat);
Serial.print(", ");
Serial.print(lon);
Serial.print(" Fix age: ");
Serial.print(age); Serial.println("ms.");
Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print("
Time(hhmmsscc): ");
Serial.print(time);
Serial.print(" Fix age: "); Serial.print(age);
Serial.println("ms.");
Serial.print("Alt(cm): "); Serial.print(gps.altitude());
Serial.print(" Speed(mps): "); Serial.print(gps.f_speed_mps());
// setting GSM module
SIM900A.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
delay(1000); // Delay of 1000 milli seconds or 1 second
// sending location from which code word had come
SIM900A.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r"); //
Replace x with mobile number
Serial.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
delay(1000);
SIM900A.print("Lat/Long(10^-5 deg): ");
SIM900A.print(lat);
SIM900A.print(", ");
SIM900A.print(lon);
SIM900A.print(" Fix age: ");
SIM900A.print(age); SIM900A.println("ms.");
SIM900A.print("Date(ddmmyy): "); SIM900A.print(date);
SIM900A.print(" Time(hhmmsscc): ");
SIM900A.print(time);
SIM900A.print(" Fix age: "); SIM900A.print(age);
SIM900A.println("ms.");
SIM900A.print("Alt(cm): "); SIM900A.print(gps.altitude());
SIM900A.print(" Speed(mps): "); SIM900A.print(gps.f_speed_mps());
SIM900A.println((char)26);// ASCII code of CTRL+Z
delay(1000);
}
}
}
delay(100);
}
String readSIM900A()
{
String buffer;
while (SIM900A.available())
{
char c = SIM900A.read();
buffer.concat(c);
delay(10);
}
return buffer;
}
P.S : I have changed the pins for GSM and rest part is same. Except adding AltSoftSerial it is a library same as SoftwareSerial (Download it from manage libraries and it requires pins 8 and 9). Don't change pin number in sketch change the connections.

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
}
}

Why Arduino int can't count over 14464?

I got some problem about reading from MPU6050 and then write to SD card.
Actually I could successfully do the read-and-write, but I found Arduino UNO can't count over 14464!?
I set every line of my data that is:
count, time(millis()), ax, ay, az, gx, gy, gz
It could record the data right till count to 14464 (I) and it will end the loop automated.
It really bothers me... and it seems no one face this problem before.
Here is my code:
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
//SD card here
#include <SPI.h>
#include <SD.h>
File myFile;
//////////Global Variable Here//////////
int16_t ax, ay, az;
int16_t gx, gy, gz;
int count = 1;
//set sec & count_limit
int set_time = 1000 * 60;
int count_limit = 80000;
int BTN = 7;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO
//Set LED
#define R_PIN 8
#define G_PIN 9
bool blinkState_R = false;
bool blinkState_G = false;
void setup() {
// configure Arduino LED for
pinMode(R_PIN, OUTPUT);
pinMode(G_PIN, OUTPUT);
pinMode(BTN, INPUT);
digitalWrite(G_PIN, HIGH);
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// use the code below to change accel/gyro offset values
accelgyro.setXGyroOffset(59);
accelgyro.setYGyroOffset(42);
accelgyro.setZGyroOffset(-8);
accelgyro.setXAccelOffset(1359);
accelgyro.setYAccelOffset(-1620);
accelgyro.setZAccelOffset(1917);
/////////////////////////////////////////////////////////////////////
//SD card Initailize
/////////////////////////////////////////////////////////////////////
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
digitalWrite(R_PIN, HIGH);
return;
}
Serial.println("initialization done.");
digitalWrite(R_PIN, LOW);
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// Check to see if the file exists:
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// delete the file:
Serial.println("Removing example.txt...");
SD.remove("example.txt");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
delay(3000);
////////////////////////////////////////////////////////////////////////////////
//SD END
////////////////////////////////////////////////////////////////////////////////
digitalWrite(G_PIN, LOW);
}
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
blinkState_R = !blinkState_R;
digitalWrite(R_PIN, blinkState_R);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
////////////////////////////////////////////
// Write to SD Card
///////////////////////////////////////////
// write data to file
if(count <= count_limit ){
myFile = SD.open("IMU_LOG.txt", FILE_WRITE);
Serial.print(count);Serial.print("\t"); myFile.print(count); myFile.print("\t");
Serial.print(millis()); Serial.print("\t"); myFile.print(millis()); myFile.print("\t");
Serial.print(ax); Serial.print("\t"); myFile.print(ax); myFile.print("\t");
Serial.print(ay); Serial.print("\t"); myFile.print(ay); myFile.print("\t");
Serial.print(az); Serial.print("\t"); myFile.print(az); myFile.print("\t");
Serial.print(gx); Serial.print("\t"); myFile.print(gx); myFile.print("\t");
Serial.print(gy); Serial.print("\t"); myFile.print(gy); myFile.print("\t");
Serial.print(gz); Serial.print("\n"); myFile.print(gz); myFile.print("\n");
myFile.close();
delay(5);
blinkState_G = !blinkState_G;
digitalWrite(G_PIN, blinkState_G);
}else{
while(1){
Serial.print("Process done.\n");
digitalWrite(G_PIN, OUTPUT);
delay(2000);
}
count= count + 1 ;
}
You should be getting a compiler warning here.
int count_limit = 80000;
The maximum value of int on your platform is 32,767. When you set an int to something larger, the behavior is undefined, which is bad news because it means that your program is incorrect.
In this particular case, you might notice that 80000 = 14464 + 216, which explains why it stopped at 14464, if int is 16 bits long.
You will need to use long if you want to count higher than 65,535.
long count_limit = 80000L;
long count = 1;

Send Mirf values with ethercard

I have project where I'm getting data over nRF24L01 and using Mirf to that. Now I'm working for Hub which need to send data to my webservice. For ethernet my choice was ENC28j60 with ethercard library.
Question : How I can wait data from Mirf and just send data forward with Ethercard browseUrl? I can send data without Mirf but there's some loop which I'm not understand.
My code :
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <EtherCard.h>
// Set network settings
static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };
byte Ethernet::buffer[700];
static uint32_t timer;
// My webservice
const char website[] PROGMEM = "my.webservice.com";
// Mirf variables
int tmpVal1;
// Local components
const int Yellow = 6;
const int Blue = 5;
void setup() {
Serial.begin(57600);
// Setup leds
pinMode(Yellow, OUTPUT);
digitalWrite(Yellow, LOW);
pinMode(Blue, OUTPUT);
digitalWrite(Blue, LOW);
setupMirf();
setupEthernet();
}
void loop() {
// Waiting to get date from Mirf
while (!Mirf.dataReady()) {
//ether.packetLoop(ether.packetReceive());
}
Mirf.getData((byte *)&tmpVal1);
Serial.print(tmpVal1);
Serial.println(F(" C"));
// Receive responses
ether.packetLoop(ether.packetReceive());
if (millis() > timer) {
timer = millis() + 5000;
//Serial.println();
Serial.println("Sending data to webservice : ");
ether.browseUrl(PSTR("/sendingdata.asmx/sendingdata?"), "Device=100&DeviceValue=80", website, my_callback);
}
//ShowLedNotification();
}
// called when the client request is complete
static void my_callback (byte status, word off, word len) {
Serial.println(">>>");
Ethernet::buffer[off+300] = 0;
Serial.print((const char*) Ethernet::buffer + off);
Serial.println("...");
digitalWrite(Blue,HIGH);
delay(200);
digitalWrite(Blue,LOW);
}
void ShowLedNotification() {
if (tmpVal1 > 0 ) {
digitalWrite(Yellow, HIGH);
delay(1000);
digitalWrite(Yellow, LOW);
}
else
{
digitalWrite(Blue, HIGH);
delay(1000);
digitalWrite(Blue, LOW);
}
}
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
//Setting up network and getting DHCP IP
void setupEthernet() {
Serial.println(F("Setting up network and DHCP"));
Serial.print(F("MAC: "));
for (byte i = 0; i < 6; ++i) {
Serial.print(mymac[i], HEX);
if (i < 5)
Serial.print(':');
}
Serial.println();
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println(F("Failed to access Ethernet controller"));
Serial.println(F("Setting up DHCP"));
if (!ether.dhcpSetup())
Serial.println(F("DHCP failed"));
ether.printIp("My IP: ", ether.myip);
ether.printIp("Netmask: ", ether.netmask);
ether.printIp("GW IP: ", ether.gwip);
ether.printIp("DNS IP: ", ether.dnsip);
// Check network connection
if (!ether.dnsLookup(website))
Serial.println("DNS failed");
ether.printIp("SRV: ", ether.hisip);
}
void setupMirf() {
//Initialize nRF24
Serial.println(F("Initializing Mirf"));
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
Mirf.setRADDR((byte *)"serv1");
Mirf.payload = sizeof(tmpVal1);
// we use channel 90 as it is outside of WLAN bands
// or channels used by wireless surveillance cameras
Mirf.channel = 90;
Mirf.config();
}
Did get that work. Now using if clause not while Mirf.dataReady()
void loop() {
if (Mirf.dataReady()) {
Mirf.getData((byte *)&tmpVal1);
Serial.print(tmpVal1);
Serial.println(F(" C"));
ShowLedNotification();
// Send data to webservice
if (millis() > timer) {
timer = millis() + 5000;
Serial.println("Sending data to webservice");
String myVarsStr = "Device=";
myVarsStr += myDeviceID;
myVarsStr += "&DeviceValue=";
myVarsStr += tmpVal1;
char myVarsCh[40];
myVarsStr.toCharArray(myVarsCh, 40);
ether.browseUrl(PSTR("/receivedata.asmx/ReceiveData?"), myVarsCh, website, my_callback);
}
}
else
{
word pos = ether.packetReceive();
word len = ether.packetLoop(pos);
delay(200);
}
}

Resources