I am trying to make a cat feeder for my cats. Everything works just fine without implementing sleep mode... I tried implementing sleep mode to save my electric bill and batteries... But unfortunately I can not find a way to do it. Until the first sleep reader is working fine, then it stops working. Even if it reads some kind of id, value of it is incorrect. I have moved serial reading part to loop() method. What I am doing wrong or what can I try to make it work... ? I do not have any electrical engineering background so any help would be very appreciated.
#include <avr/sleep.h>
#include <avr/power.h>
#include <SoftwareSerial.h>
// Define RX and TX pins for SoftwareSerial (optional)
const int rxPin = 10;
const int txPin = 11;
SoftwareSerial mySerial(rxPin, txPin);
enum Rfid134_Error {
Rfid134_Error_None,
// from library
Rfid134_Error_PacketSize = 0x81,
Rfid134_Error_PacketEndCodeMissmatch,
Rfid134_Error_PacketChecksum,
Rfid134_Error_PacketChecksumInvert
};
struct Rfid134Reading {
uint16_t country;
uint64_t id;
bool isData;
bool isAnimal;
uint16_t reserved0;
uint32_t reserved1;
};
enum DfMp3_Packet {
Rfid134_Packet_StartCode = 0,
Rfid134_Packet_Id = 1,
Rfid134_Packet_Country = 11,
Rfid134_Packet_DataFlag = 15,
Rfid134_Packet_AnimalFlag = 16,
Rfid134_Packet_Reserved0 = 17,
Rfid134_Packet_Reserved1 = 21,
Rfid134_Packet_CheckSum = 27,
Rfid134_Packet_CheckSumInvert = 28,
Rfid134_Packet_EndCode = 29,
Rfid134_Packet_SIZE = 30
};
uint64_t HexLsbAsciiToUint64(char* text, uint8_t textSize) {
uint64_t value = 0;
uint8_t i = textSize;
do {
i--;
uint8_t digit = text[i];
if (digit >= 'A') {
digit = digit - 'A' + 10;
} else {
digit = digit - '0';
}
value = (value << 4) + digit;
} while (i != 0);
return value;
};
void setup() {
// Initialize hardware serial communication
Serial.begin(115200);
// Initialize software serial communication (optional)
mySerial.begin(9600);
mySerial.setTimeout(1000);
while (!mySerial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Arduino is going to sleep...");
// Set up the sleep mode
set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Choose appropriate sleep mode
// Enable sleep mode
sleep_enable();
// Attach the interrupt to wake up the Arduino upon receiving serial data
attachInterrupt(digitalPinToInterrupt(rxPin), wakeUp, LOW);
}
void loop() {
// Put the Arduino to sleep
sleep_mode(); // The program will continue from here after waking up
// Disable sleep mode after waking up
sleep_disable();
// Detach the interrupt
detachInterrupt(digitalPinToInterrupt(rxPin));
// Perform tasks after waking up
Serial.println("Arduino woke up!");
while (mySerial.available() >= Rfid134_Packet_SIZE) {
Serial.println("Working");
char packet[Rfid134_Packet_SIZE];
packet[Rfid134_Packet_StartCode] = mySerial.read();
//check for the first byte being the packet start code
if (packet[Rfid134_Packet_StartCode] != 0x02) {
Serial.println("Rfid134_Error_None");
}
uint8_t read;
read = mySerial.readBytes(&(packet[Rfid134_Packet_Id]), Rfid134_Packet_SIZE - 1);
if (read != Rfid134_Packet_SIZE - 1) {
Serial.println("Rfid134_Error_PacketSize");
}
if (packet[Rfid134_Packet_EndCode] != 0x03 && packet[Rfid134_Packet_EndCode] != 0x07) {
Serial.println("Rfid134_Error_PacketEndCodeMissmatch");
}
// calculate checksum
uint8_t checksum = 0;
for (uint8_t i = Rfid134_Packet_Id; i < Rfid134_Packet_CheckSum; i++) {
checksum = checksum ^ packet[i];
}
// test checksum
if (checksum != packet[Rfid134_Packet_CheckSum]) {
Serial.println("Rfid134_Error_PacketChecksum");
}
if (static_cast<uint8_t>(~checksum) != static_cast<uint8_t>(packet[Rfid134_Packet_CheckSumInvert])) {
Serial.println("Rfid134_Error_PacketChecksumInvert");
}
Rfid134Reading reading;
// convert packet into the reading struct
reading.id = HexLsbAsciiToUint64(&(packet[Rfid134_Packet_Id]), Rfid134_Packet_Country - Rfid134_Packet_Id);
reading.country = HexLsbAsciiToUint64(&(packet[Rfid134_Packet_Country]), Rfid134_Packet_DataFlag - Rfid134_Packet_Country);
reading.isData = packet[Rfid134_Packet_DataFlag] == '1';
reading.isAnimal = packet[Rfid134_Packet_AnimalFlag] == '1';
reading.reserved0 = HexLsbAsciiToUint64(&(packet[Rfid134_Packet_Reserved0]), Rfid134_Packet_Reserved1 - Rfid134_Packet_Reserved0);
reading.reserved1 = HexLsbAsciiToUint64(&(packet[Rfid134_Packet_Reserved1]), Rfid134_Packet_CheckSum - Rfid134_Packet_Reserved1);
print_uint64_t(reading.id);
}
// Prepare to sleep again by enabling sleep mode and attaching the interrupt
sleep_enable();
attachInterrupt(digitalPinToInterrupt(rxPin), wakeUp, LOW);
}
// Interrupt service routine to wake up the Arduino
void wakeUp() {
}
void print_uint64_t(uint64_t num) {
char rev[128];
char *p = rev+1;
while (num > 0) {
*p++ = '0' + ( num % 10);
num/= 10;
}
p--;
/*Print the number which is now in reverse*/
while (p > rev) {
Serial.print(*p--);
}
Serial.println();
}