Sorry about that. I maybe didn't make it clear that if I un comment the third line down in the ISR (rxNewBit ^= 0x01UL;) the code no longer works.
So if I run this code:
//Global
volatile unsigned long rxFrame; //this is the raw unprocessed frame
ISR(TIMER1_COMPA_vect) {
byte rxNewBit = PIND & B00001000; //Get input pin status
rxNewBit = rxNewBit>>3; //Shift bit to position 0
rxNewBit ^= 0x01UL;
rxFrame += (rxNewBit<<rxIndex); //Add to frame
if (rxIndex == 31) {
rxIndex = 0;
frameToProcess = true;
TCCR1C &= ~B10000000; //Turn off force output compare for channel A
TIMSK1 &= ~B00000010; //Turn off output compare match interupt enable
recievingFrame = false;
}
else {
rxIndex ++; //Increment index position
OCR1A = rxTime[rxIndex]; //Set Output compare register to next value
}
}
I get this:
Here is Frame 1111110
I need all 32 bits of the unsigned long, but it is truncated down to 8.
Here is my code in its entirety:
const byte rxPin = 3; //output from sensor terminal three connected through NPN transistor. Pin 3 is interupt 1. Use PIND & (1<<rxPin) (or PIND & B00001000) to read status
const byte txPin = 4; //output from Arduino to send serial frames. Set and clear pin with bitSet(PORTD, txPin) and bitClear(PORTD, txPin)
boolean okToStartFrame;
boolean recievingFrame;
unsigned int sensorData [3]; //Stores incoming sensor data. 1 is temp, 2 is moisture 1 (frame type 2) 3 is moisture 2 (frame type 3)
unsigned int sensorDataAge[3]; //Age of last reading
unsigned int rxFrameErrors; //counter to incrememnt when a frame error is encountered
volatile boolean frameToProcess; //toggle this on when a new frame has been recieved
volatile unsigned int rxTime [] = {876,2628,4380,6132,7884,9636,11388,13140,14892,16644,18396,20148,21900,23652,25404,27156,28908,30660,32412,34164,35916,37668,39420,41172,42924,44676,46428,48180,49932,51684,53436,55188};
volatile byte rxIndex = 0; //Index that is incremented with each bit recieved
volatile unsigned long rxFrame; //this is the raw unprocessed frame as recieved from sensor
void setup() {
Serial.begin (9600); //Debug serial
pinMode (rxPin, INPUT);
//digitalWrite (rxPin, HIGH); //turn on pullup resistor
EICRA |= B0001000; //Configure external interupt 1 to FALLING
SREG |= B10000000; //Global interupts enable (same as sei()?)
TCCR1B |= (1<<CS10); //Set prescaler for 1
//TCCR1C &= ~B10000000; //Added for debug Turn off force output compare for channel A
//TIMSK1 &= ~B00000010; //Added for debug Turn off output compare match interupt enable
Serial.println("Starting up...");
}
//Add code to check if rx pin has stayed high for frame reset time before enabling okToStartFrame the first time
void loop() {
unsigned long currentMillis = millis();
unsigned long lastFrameRecievedTime; //Last time a frame was received. Reset when frame is sent to process. Use to check for enabling of pin interupt.
const unsigned long frameResetTime = 25; //time for line to be idle before being able to recieve a new frame.
if (!okToStartFrame) {
if (currentMillis - lastFrameRecievedTime > frameResetTime) {
okToStartFrame = true;
EIFR |= B00000010; //Clear interupt 1 flag in case it is on.
EIMSK |= B00000010; // Enable interupt 1
Serial.print("Interupt 1 is now enabled. Current time is ");
Serial.println(millis());
}
}
if (frameToProcess) {
Serial.println("Now calling process frame function...");
processFrame();
lastFrameRecievedTime = millis();
okToStartFrame = false;
}
}
void processFrame() {
//rxFrame = ~rxFrame;
Serial.print("Here is Frame ");
Serial.println(rxFrame, BIN);
unsigned long frameCheck = rxFrame &= 0xFE0001F9; //This hex number is equivalent to B11111110000000000000000111111001
Serial.print("Here is frameCheck");
Serial.println(frameCheck, BIN);
if (frameCheck != 0x2000001) { //0x2000001 is equivalent to B10000000000000000000000001 which is the start and stop bit only.
rxFrameErrors++; //Frame error
Serial.print("Frame error. Error counter is ");
Serial.println(rxFrameErrors);
}
else {
byte address = (rxFrame &= 0x6)>>1; //0x6 is B110 and masks the two address bits and then shifts them one place to the right to remove the start bit
Serial.print("Frame received from address ");
Serial.println(address);
sensorData[address] = (rxFrame &= 0x1FFFE00)>>9; // 0x1FFFE00 is equivalent to B1111111111111111000000000 which masks all except 16 data bits.
Serial.print("Sensor data recieved is ");
Serial.println(sensorData[address]);
sensorDataAge[address] = millis();
}
frameToProcess = false;
}
ISR(INT1_vect) { //This is called when a start bit is detected
unsigned char sreg;
recievingFrame = true;
EIMSK &= ~B00000011; //Disable interupt 1
/*sreg = SREG; // Save global interrupt flag
cli(); // Disable interrupts //not sure if this is needed
TCNT1 = 0; //Reset timer1 to zero
SREG = sreg;// Restore global*/
TCNT1 = 0; //Reset timer1 to zero
OCR1A = rxTime[rxIndex]; //Set Output compare register to first value in array
TCCR1C |= B10000000; //Force output compare for channel A enabled
TIMSK1 |= B00000010; //Output compare A match interupt enable TIFR1.OCFA flag is set and ISR fires when compare matches
//Serial.println("In INT1");
}
ISR(TIMER1_COMPA_vect) {
byte rxNewBit = PIND & B00001000; //Get input pin status
rxNewBit = rxNewBit>>3; //Shift bit to position 0
rxNewBit ^= 0x01UL;
rxFrame += (rxNewBit<<rxIndex); //Add to frame
if (rxIndex == 31) {
rxIndex = 0;
frameToProcess = true;
TCCR1C &= ~B10000000; //Turn off force output compare for channel A
TIMSK1 &= ~B00000010; //Turn off output compare match interrupt enable
recievingFrame = false;
}
else {
rxIndex ++; //Increment index position
OCR1A = rxTime[rxIndex]; //Set Output compare register to next value
}
}