Hi Mikal
my code is for a wireless RFID reader. I would like to check battery levels and look for tags in my main loop. As has been reported in other threads - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201703850/9#9 - SoftwareSerial's read function blocks until there is a tag available to read, making it 'impossible' to perform both checks. The available function in NewSoftSerial would hopefully resolve this.
Much thanks for the support.
Roger
#include <NewSoftSerial.h>
#include <avr/sleep.h>
#include <string.h>
#define BATTERY_CHECK_INTERVAL 60000
#define SIX_HOUR 952
#define FIVE_HOUR 945
#define FOUR_HOUR 936
#define THREE_HOUR 926
#define TWO_HOUR 910
#define ONE_HOUR 881
#define ZERO_HOUR 836
// RFID reader for Arduino
// Wiring version by BARRAGAN <http://people.interaction-ivrea.it/h.barragan>
// Modified for Arudino by djmatic
// Modified to use SoftwareSerial by Erik Sjodin <http://www.eriksjodin.net>
// Modified for use in TagMat by Roger Meintjes <http://www.doc.gold.ac.uk/~ma701rm/>
/*
* RFID_Scratch03 (Arduino)
*
* Tests communication between RFID, ArduinoXbee, Processing & Scratch.
* Reads in RFID tag code from reader and writes it out through Xbee.
* Code is written out as the String start_byte<10 char code>stop_byte.
*
* Battery is checked once every minute.
* Battery charge written out as String start_byte<10 char charge in hours>stop_byte.
*
* Connect:
* Arduino pin 3 to RFID SOUT
* Arduino GND to RFID GND
* Arduino Digital pin 2 to RFID /ENABLE
* Arduino 5v to RFID VCC
*/
char code[13] = "";
char charge[13] = "";
char baseString[11] = {72, 82, 95, 67, 72, 65, 82, 71, 69, 13, 0};
unsigned long timeNow = 0;
int batteryLevel = 0;
int val = 0;
int bytesRead = 0;
int rx = 3;
int tx = 4;
int batteryPin = 5;
int rfidEnable = 2;
//set up software serial port
NewSoftSerial softSerial = NewSoftSerial(rx, tx);
void setup()
{
timeNow = millis();
pinMode(rx, INPUT);
pinMode(tx, OUTPUT);
pinMode(batteryPin, INPUT);
pinMode(rfidEnable, OUTPUT);
softSerial.begin(2400); //set software serial port to reader baud rate
Serial.begin(9600); //set hardware serial port to xbee baud rate
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep_mode to most power saving
//initialize reader with reset cycle
digitalWrite(rfidEnable, LOW);
delay(100);
digitalWrite(rfidEnable, HIGH);
delay(100);
digitalWrite(rfidEnable, LOW);
delay(100);
}
void loop() {
if((millis() - timeNow) > BATTERY_CHECK_INTERVAL) {
checkBattery();
timeNow = millis();
}
else {
checkReader();
}
}
void checkReader() {
digitalWrite(rfidEnable, LOW);
if(softSerial.available() > 0) {
//check for start byte
if((val = softSerial.read()) == 10) {
bytesRead = 0;
code[bytesRead] = val;
bytesRead++;
//do nothing until all twelve bytes have arrived
while(softSerial.available() < 12);
//read in code and stop byte
while(bytesRead < 12) {
val = softSerial.read();
code[bytesRead] = val;
bytesRead++;
}
digitalWrite(rfidEnable, HIGH);
//check for the stop byte
if(val == 13) {
Serial.print(code);
}
delay(250);
}
}
}
void checkBattery() {
batteryLevel = analogRead(batteryPin);
charge[0] = 10; //start byte
charge[2] = 0; //termination byte
if(batteryLevel > SIX_HOUR) {
charge[1] = 54; //ASCII 6
}
else if(batteryLevel > FIVE_HOUR) {
charge[1] = 53; //ASCII 5
}
else if(batteryLevel > FOUR_HOUR) {
charge[1] = 52; //ASCII 4
}
else if(batteryLevel > THREE_HOUR) {
charge[1] = 51; //ASCII 3
}
else if(batteryLevel > TWO_HOUR) {
charge[1] = 50; //ASCII 2
}
else if(batteryLevel > ONE_HOUR) {
charge[1] = 49; //ASCII 1
}
else if(batteryLevel > ZERO_HOUR) {
charge[1] = 48; //ASCII 0
}
else {
sleep_mode();
}
Serial.print(strcat(charge, baseString)); //create and write charge string
}