How can I read date and time data from RTC of sim900 module using arduino? - arduino

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
SMSGSM sms;
boolean started=false;
int count = 0;
void setup()
{
pinMode(5, INPUT); // input pin for switch
Serial.begin(9600);
if (gsm.begin(2400))
{
Serial.println("\nstatus=READY");
started=true;
}
else Serial.println("\nstatus=IDLE");
delay(1000);
}
void loop()
{
if (digitalRead(5)==1)
{
delay(500);
if (digitalRead(5)==1)
{
count = count+1;
/*if(started)
{
if (sms.SendSMS("+12345678", "ALARM"))
Serial.println("\nSMS sent OK");
}*/
Serial.println("Count = ");
Serial.println(count);
readtime();
Serial.println(content);
}
}
else
{
Serial.println("Normal");
}
}
I use sim 900 with arduino to detect change of input pin 5 and then ALARM to user. I have a few question that need your help
How can I know which pin that sim 900 use to communicated for sent sms? I use jumper at D2 and D3. Did it use these two pins? because in my program I use an .h include file which I didn't know detail inside it.
How can I read date and time data from RTC in sim 900 module and store in a variable and use them for data logger later? I know that if I have already set date and time in RTC, it can be read by "AT+CCLK?" and it return date and time data. But how can I use this command in my program?

I found this code and work for me. First you ask for time and then expect answers and parse it.
const char* const SIM900::getTimeStamp(){
Serial2.print("AT+CCLK?"); //SIM900 AT command to get time stamp
Serial2.print(13,BYTE);
delay(2000);
if (Serial2.available()>0){
int i = 0;
while (Serial2.available()>0){
timeStamp[i]=(Serial2.read());
i++;
}
}
int years = (((timeStamp[25])-48)*10)+((timeStamp[26])-48);
int months = (((timeStamp[22])-48)*10)+((timeStamp[23])-48);
int days = (((timeStamp[19])-48)*10)+((timeStamp[20])-48);
int hours = (((timeStamp[28])-48)*10)+((timeStamp[29])-48);
int mins = (((timeStamp[31])-48)*10)+((timeStamp[32])-48);
int secs = (((timeStamp[34])-48)*10)+((timeStamp[35])-48);
//YOUR CODE HERE
}

Related

I am creating this temp monitoring system

I am creating this temp monitoring system...Therefore, i want to get messages/alerts when the temperature are below 6 and again when they come back to above 6. Note: I don't want the alert (sendMailNormalValue():wink: to come when the system boots up....How do I deactivate the sendMailNormalValue(); and activate it only when the temp are below 6 (only to alert me when comes back to above 6)..
#include <OneWire.h>
#include <DallasTemperature.h>
// GPIO where the DS18B20 is connected to
const int oneWireBus = 5;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
//========================================
float t;
int period = 30000;
unsigned long time_now = 0;
bool DisplayFirstTime = true;
int period1 = 30000;
unsigned long time_now1 = 0;
void sendMailBelowValue(){
}
void sendMailNormalValue(){
}
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
}
void loop() {
// put your main code here, to run repeatedly:
sensors.requestTemperatures();
t = sensors.getTempCByIndex(0);
float p=t-2;
// Check if any reads failed and exit early (to try again).
if (isnan(t)) {
Serial.println("Failed to read from sensor !");
delay(500);
return;
}
if (t>6){
if(millis() > time_now + period){
time_now = millis();
sendMailNormalValue();
Serial.print ("You got messagae");
}
}
if (t<6){
if(millis() > time_now1 + period1 || DisplayFirstTime){
DisplayFirstTime = false;
time_now = millis();
sendMailBelowValue();
}
}
}
I think I understand what you mean. On error (temp < 6), you want to send an email every 30 seconds; when the teperature reaches 6 or mode, send a single email to say the error condition has been fixed. On boot, only send an email if in error.
If that's it, you'll need to keep track of the error condition using a global flag.
// ...
bool tempError; // initialized in setup()
void setup()
{
// ...
float t;
for(;;) // loop until we get a valid reading.
{
t = sensors.getTempCByIndex(0);
if (!isnan(t))
break;
Serial.println("Failed to read from sensor !");
delay(500);
}
tempError = (t < 6);
}
void loop()
{
// read temp and check sensor...
// ...
if (t < 6)
{
tempError = true;
// send error email, set timer, etc...
}
else if (tempError)
{
// temp is now fine, after being too low.
tempError = false; // Clear error flag.
// send OK email, only once.
// Don't forget to clear the 30 second email timer !!!
}
}
Usually, you'd want some hysteresis in an alert system. You should consider waiting some seconds after the temperature has been 'fixed' before sending the 'OK' email. Otherwise you may end up getting lots of fail/fixed emails when the temperature is around 6 degrees. This is usually done with a simple state machine engine, but that is a bit beyond the scope of this questkon.

Arduino AccelStepper Library: Instant speed never reaches set speed

I am trying to develop a arduino code which runs a stepper motor with C# program via serial communication. I also use Accelstepper library, especially moveTo() and run() functions. I sent maxSpeed and step values as 3500 and 200.000 from C# and motor start to run immediately. I sure that it completes all steps, but after a while, I noticed that stepper motor never reaches its max Speed and it stuck at 3200-3300 range. So because of that finish time is increased. If I give steps more than 200.000, the gap between estimated finish time and real finish time is increased exponentially. If I sent speed as 1000, real speed more or less 970. I have to use acceleration function by the reason of needed torque. Then I search the problem and some people said that it occurs because of Accelstepper library which consist run() function and other stuff that I wrote in the loop section. Especially I could not ensure the reason of the problem is Arduino, AccelStepper library or code that I wrote. Can you please help me to solve problem?
NOTE: Arduino Mega 2560 is used.
Arduino code is below:
#include <AccelStepper.h>
#include <stdio.h>
#define STEP_PIN_C 5 //31
#define DIRECTION_PIN_C 23 //32
#define ENABLE_PIN_C 24 //33
#define SET_ACCELERATION 600.0
AccelStepper stepper(1, STEP_PIN_C, DIRECTION_PIN_C);
unsigned long oldTime=0;
unsigned long now;
float newSpeed;
float maxSpeed = 3500.0;
bool newDataBit, runAllowed = false,addingProg=false,mainProg=false;
char commandChar;
long currentPosition;
long int steps = 0, mainNewStep, addedNewStep,memMainStep;
void checkSerial();
void checkRunning();
void stopMotor();
void runMotor();
void sendInfo();
const unsigned long delayTime = 1000;
unsigned long timer;
int count = 0;
bool running = false;
void setup()
{
Serial.begin(9600);
pinMode(ENABLE_PIN_C, OUTPUT);
digitalWrite(ENABLE_PIN_C, HIGH);
stepper.setCurrentPosition(0); //initial value
stepper.setMaxSpeed(0.0); //initial value
stepper.setAcceleration(SET_ACCELERATION); //initial value
}
void loop()
{
sendInfo();
checkRunning();
checkSerial();
}
void checkRunning()
{
if (runAllowed == true)
{
if (stepper.distanceToGo() == 0)
{
stopMotor();
checkSerial();
}
else
{
runMotor();
checkSerial();
}
}
}
void checkSerial()
{
if (Serial.available())
{
newDataBit = true;
commandChar = Serial.read();
}
if (newDataBit == true)
{
///DoStuff depends on what is received as commandChar via serial port
mainProgram(stepper.currentPosition(),newSpeed,mainNewStep);
newDataBit = false;
}
}
void runMotor(){
digitalWrite(ENABLE_PIN_C, LOW);
stepper.run();
running = true;
}
void stopMotor(){
stepper.setCurrentPosition(0);
digitalWrite(ENABLE_PIN_C, HIGH);
stepper.stop();
running = false;
timer = millis() + delayTime;
}
void mainProgram(long currentPositionValue,float maxSpeedValue,long stepValue)
{
mainProg = true;
if (stepper.distanceToGo() == 0) //YOLUMU TAMAMLADIM
{
addingProg = false;
steps = stepValue;
stepper.setCurrentPosition(currentPositionValue);
//stepper.setSpeed(0);
stepper.setMaxSpeed(maxSpeedValue);
stepper.moveTo(steps);
}
else
{
steps = stepValue + steps;
stepper.setCurrentPosition(currentPositionValue);
//stepper.setSpeed(0);
stepper.setMaxSpeed(newSpeed);
stepper.moveTo(steps);
}
}
void sendInfo(){
now = millis();
if(now-oldTime > 1000){ //saniyede 1
Serial.print(stepper.currentPosition());
Serial.print(" ");
Serial.print(stepper.isRunning());
Serial.print(" ");
Serial.println(stepper.speed());
oldTime = now;
}
}
From AccelStepper documentation:
The fastest motor speed that can be reliably supported is about 4000
steps per second at a clock frequency of 16 MHz on Arduino such as Uno
etc.
This is if you do nothing else but running the stepper.
You check your serial interface and send multiple lines every second. Both is quite expensive.

Need some help in understanding some codes

I'm using RFID RC522 module in Arduino what the code does is, whenever the RFID tag is close to the reader it will read the tag no, with the current timestamp. But i need help in understanding the code line by line. I've understood a few lines which commented in the code but the rest i need help. Thank you
#include <RFID.h>
#include <SPI.h>
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN, RST_PIN);
int serNum[4];
String cardno;
int interval = 15000; // millisec
long now = 0;
long lasttime = millis(); //millis() no.of millisec the sketch was runnning
String readerID = "100"; // This is the reader ID
void setup() {
Serial.begin(9600); //setting data rate in bits per second 9600
SPI.begin();
rfid.init();
}
void loop() {
now = millis();
if (rfid.isCard()) {
if (rfid.readCardSerial()) {
lasttime = now;
cardno = String(rfid.serNum[0]) +
String(rfid.serNum[1]) +
String(rfid.serNum[2]) +
String(rfid.serNum[3]) +
String(rfid.serNum[4]);
Serial.print(readerID);
Serial.print(":");
Serial.println(cardno); //printing the cardno in the serial monitor
}
}
rfid.halt();
delay(1000);
}
There are unused variables in your code. Let's get rid of them so that it is less confusing. I also added comments that explain the if statements.
#include <RFID.h>
#include <SPI.h>
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN, RST_PIN);
String cardno;
String readerID = "100";
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.init();
}
void loop() {
if (rfid.isCard()) { // Look for a card. If found, return true.
if (rfid.readCardSerial()) { // Read the serial number of the card. if successful, return true.
cardno = String(rfid.serNum[0]) +
String(rfid.serNum[1]) +
String(rfid.serNum[2]) +
String(rfid.serNum[3]) +
String(rfid.serNum[4]);
Serial.print(readerID);
Serial.print(":");
Serial.println(cardno);
}
}
rfid.halt();
delay(1000);
}
Guessing from your comment, I think you want to understand how RFID class is implemented. I suggest looking at RFID.h and RFID.cpp.
RFID class has an array called serNum. My guess is that when you call readCardSerial(), an instance of RFID tries to store a card number in this array. If the operation is successful, it returns true.

How to increase beacon scan sample rate use esp32

I using the esp32 to detection beacon through rssi of beacon, but i meet some problem, first is rssi value is no stable so i need more sample of rssi, the second problem is esp32 scan sample rate is too slow, that faster speed only have one second scan rate, below is my used code
#include <BLEAdvertisedDevice.h>
#include <BLEDevice.h>
#include <BLEScan.h>
const int PIN = 2;
const int CUTOFF = -60;
void setup() {
pinMode(PIN, OUTPUT);
BLEDevice::init("");
}
void loop() {
BLEScan *scan = BLEDevice::getScan();
scan->setActiveScan(true);
BLEScanResults results = scan->start(1);
int best = CUTOFF;
for (int i = 0; i < results.getCount(); i++)
{
BLEAdvertisedDevice device =
results.getDevice(i);
int rssi = device.getRSSI();
if (rssi > best) {
best = rssi;
}
}
digitalWrite(PIN, best > CUTOFF ? HIGH :
LOW);
}
but i want to mor rssi sample, i tried change scan->start(1) to scan->start(0), but result is not return, how to do can solve lower sample problem, or use another board?
The problem is that you do all of the "work" in the loop.
Are you aware of the fact that an ESP32 microcontroller runs at 240 MHz
I guess your loop time is about 400 Nano seconds.
So how would your device know if and how much devices are found.
You are trying to do something with the scan results just after scan start.
To get around this problem there is a BLEAdvertisedDeviceCallbacks in the Arduino for ESP32 code.
This callback will return a result for every device it finds.
Here is an example from GITHUB (ESP32_BLE_Arduino by Neil Kolban)https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_scan/BLE_scan.ino
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets
/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
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(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}
This to give you an idea on how it works, tweak it to meet your own needs.

Arduino Xbee Data parsing

Im sorry to make a post like this but i have tried everything and i cant get this working!
I have two arduinos hooked up with xbee's.
One is connected to my computer recieving data and the other is bettery powered and has a Wii nunchuck attached.
I know im getting good data from the nunchcuck cause i tested it without the xbee.
But i want to send the data over serial and recieve on the other to use for something else but doesnt seem to be working. Here is the code:
Arduino with wii:
#include <Wire.h>
#include <Servo.h>
const int vccPin = A3;
const int gndPin = A2;
Servo servo;
const int dataLength = 6; // Number of bytes to request
static byte rawData[dataLength];
enum nunchuckItems {
JoyX, JoyY, accelX, accelY, accelZ, btnZ, btnC};
void setup()
{
pinMode(gndPin, OUTPUT);
pinMode(vccPin, OUTPUT);
digitalWrite(gndPin, LOW);
digitalWrite(vccPin, HIGH);
servo.attach(9);
delay(1000);
Serial.begin(9600);
nunchuckInit();
}
void loop()
{
nunchuckRead();
int joyX = getValue(JoyX);
int joyY = getValue(JoyY);
Serial.print(joyX);
Serial.print(",");
Serial.print(joyY);
Serial.println();
}
void nunchuckInit(){
Wire.begin();
Wire.beginTransmission(0x52);
Wire.write((byte)0x40);
Wire.write((byte)0x00);
Wire.endTransmission();
}
static void nunchuckRequest(){
Wire.beginTransmission(0x52);
Wire.write((byte)0x00);
Wire.endTransmission();
}
boolean nunchuckRead(){
int cnt = 0;
Wire.requestFrom(0x52, dataLength);
while (Wire.available()){
rawData[cnt] = nunchuckDecode(Wire.read());
cnt++;
}
nunchuckRequest();
if (cnt >= dataLength)
return true;
else
return false;
}
static char nunchuckDecode(byte x){
return (x ^ 0x17) + 0x17;
}
int getValue(int item){
if (item <= accelZ)
return (int)rawData[item];
else if (item == btnZ)
return bitRead(rawData[5], 0) ? 0: 1;
else if (item == btnC)
return bitRead(rawData[5], 1) ? 0: 1;
}
How could i recieve this data on the recieving arduino?
Please help its for my school project!
Thank you!!
When you read the terminal (without the Xbee) do you see line with X,Y appear ? Because if your arduino terminal see it, the problem comes from the Xbee.
If your terminal see the line, look at your Xbee with Xctu. You must set the panID on both Xbee to see them communicate. you must also make the SL address of the sender equal to the DL address of the receiver (and same for the SH/DH).
Can you say us which Arduino, Xbee, shield you use. It can help us to have more details

Resources