Would appreciate some knowledgeable advice here.
MY project consists of a "Sender" arduino (nano) carrying a S1 xbee, and a "Receiver" arduino (Uno) carrying S1 as well.
Most of the data traffic is nano ->uno, but in 2 specific cases on the receiver code (Rewind and Play cases) I need to send back a confirmation to the sender and make it turn an LED down. Now the thing is, it sometimes works and sometimes doesn't and I can't see any logic to this. Maybe I'm overflowing the Xbee modules? Maybe I'm doing some basic thing all wrong?
Really need some help here and attaching the codes.
Sender:
#include <OneButton.h>
// Movement of Optical encoder is translated to moving stepper
//
//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
int lastEncoded = 0;
int encoderValue = 0;
int lastencoderValue = 0;
int lastMSB = LOW;
int lastLSB = LOW;
//LEDs
#define realTimeLED 12 //Real Time LED
#define playLED 9 //PLay LED
#define inLED 11 //In LED
#define outLED 10 //Out LED
// Setup OneButton
OneButton realTimebutton(A4, true);
OneButton playButton (A1, true);
OneButton inButton (A3, true);
OneButton outButton (A2, true);
//Values for focus points
volatile int inPoint = 0;
volatile int outPoint = 3000;
//Values for calibrating lens and motor
int lowEnd = 0;
int highEnd = 3000;
//Blink without delay
int ledState = LOW;
long previousMillis = 0;
int ledInterval = 75;
boolean rClickedOnce = false;
boolean rLongPress = false;
boolean pClickedOnce = false;
//Value for sendFunction - to send over Xbee
int value;
//value for variable speed - to send over Xbee
int valToRemap;
int encoderValToRemap;
//Value to recieve from 2nd Xbee: when "play" or "rewind" has finished"
int dataReceive;
//Modes
int mode;
#define RealTime 1
#define Stop 2
#define REWIND 3
#define PLAY 4
#define LENSCALIB 5
void setup(){
Serial.begin(115200);
//Pinmodes
pinMode (realTimeLED, OUTPUT);
pinMode (playLED, OUTPUT);
pinMode (inLED, OUTPUT);
pinMode (outLED, OUTPUT);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
//attachInterrupt(0, updateEncoder, CHANGE);
//attachInterrupt(1, updateEncoder, CHANGE);
//Attach Click to Buttons
realTimebutton.attachClick(Click);
playButton.attachClick(ClickPlay);
inButton.attachClick(ClickIn);
outButton.attachClick(ClickOut);
//Attach Press to Real Time for calibrating lens and motor
realTimebutton.attachPress(rPress);
}
void loop(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
//only if changed value
if(lastMSB != MSB || lastLSB != LSB){
updateEncoder(MSB, LSB);
}
// keep watching the push buttons:
realTimebutton.tick();
playButton.tick();
inButton.tick();
outButton.tick();
//This was meant in order to signal "sender" arduino when the action
//on other side (play/rewind) is done. Currently does not work
if (Serial.available())
{
dataReceive = Serial.read();
if (dataReceive == 1)
{
pClickedOnce = false;
digitalWrite(playLED, LOW);
}
}
}
void updateEncoder(int MSB, int LSB){
lastMSB = MSB;
lastLSB = LSB;
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
{
encoderValue ++;
/* if (encoderValue>highEnd)
encoderValue = highEnd;*/
//Serial.println(encoderValue);
// This is a function so as to be able to to use the data
// in 2 different ways: 1/as encoder value
// 2/as speed value for play/rewind
// depending on state of switches.
sendFunction (1);
}
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
{
encoderValue --;
/*if (encoderValue<lowEnd)
encoderValue = lowEnd;*/
//Serial.println(encoderValue);
// This is a function so as to be able to to use the data
// in 2 different ways: 1/as encoder value
// 2/as speed value for play/rewind
// depending on state of switches.
sendFunction(2);
}
lastEncoded = encoded; //store this value for next time
}
//4 Buttons Click Functions
void Click() {
digitalWrite(playLED, LOW);
if (rClickedOnce == false )
{
rClickedOnce = true;
digitalWrite(realTimeLED, HIGH);
}
else
{
digitalWrite(realTimeLED, LOW);
rClickedOnce = false;
}
}
void ClickPlay () {
//terminate realtime in case it wasn't stopped
if (pClickedOnce == false)
{
pClickedOnce = true;
rClickedOnce = false;
digitalWrite(realTimeLED, LOW);
digitalWrite(playLED, HIGH);
Serial.write(4);
}
else
{
pClickedOnce = false;
digitalWrite(playLED, LOW);
}
}
void ClickIn () {
// Saving In
if (rClickedOnce == true)
{
Serial.write (3);
inPoint = encoderValue;
//Serial.println (inPoint);
blinkMark (inLED);
}
//Saving Low End of encoderVal
// else if (rLongPress == true) {
// lowEnd = encoderValue;
//Serial.print ("lowEnd = ");
//Serial.println (lowEnd);
//}
//blinkMark (inLED);
}
void ClickOut() {
//Saving Out
if (rClickedOnce == true)
{
Serial.write (5);
outPoint = encoderValue;
//Serial.println (outPoint);
blinkMark (outLED);
}
/*outPoint = stepper.currentPosition();
encoderOut = encoderValue; //saved for variable speed
Serial.print ("Out Point = ");
Serial.println (encoderOut);
else if (rLongPress ==true) {
highEnd = encoderValue;
Serial.print ("highEnd = ");
Serial.println (highEnd);
}
blinkMark (outLED);*/
}
// Press Function - calibrating lens and stepper
// not tried yet.
void rPress() {
if (rLongPress == false) {
Serial.println ("Lens Limit");
rLongPress = true;
highEnd = 4000;
lowEnd = 0;
mode = LENSCALIB;
}
else {
mode = Stop;
}
}
int blinkFunction (int y) // Blink without delay
{
unsigned long currentMillis = millis ();
if (currentMillis - previousMillis>ledInterval)
{
previousMillis = currentMillis;
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite (y, ledState);
}
}
int blinkMark (int y)
{
boolean b = HIGH;
for (int i=0;i<6;i++)
{
digitalWrite(y, b);
delay(75);
b=!b;
}
}
int sendFunction(int value)
{
// 1/Send encoder value to move stepper
if (rClickedOnce == true)
Serial.write (value);
else if (pClickedOnce == false)
{
// 2/Send remapped value to change speed of stepper
encoderValToRemap = encoderValue;
if (inPoint<outPoint)
{
if (encoderValToRemap< inPoint)
encoderValToRemap = inPoint;
if (encoderValToRemap>outPoint)
encoderValToRemap = outPoint;
}
else
{
if (encoderValToRemap>inPoint)
encoderValToRemap = inPoint;
if (encoderValToRemap<outPoint)
encoderValToRemap = outPoint;
}
//Serial.println (encoderValToRemap);
//remap value to ba able to send bytes
valToRemap = focusSpeed(encoderValToRemap);
}
}
int focusSpeed (int valToRemap)
{
//remapped value sent to "receiving" arduino to change stepper speed
//during play/rewind.
// currently after some revolutions of encoder Xbees stop communicating until reset.
valToRemap = map(valToRemap, inPoint, outPoint, 10, 30);
//Serial.print ("valToRemap");
//Serial.println (valToRemap);
Serial.write (valToRemap);
}