Widgets not working

I have created a Thing.
Added a variable called limitSwitch1 as read only bool on change.
Then created a dashboard and added the Status widget.

Added this into my code in the main loop.

  limitSwitch1 = digitalRead(A0);
  if(A0 == LOW){limitSwitch1 = false;}
  else if(A0 == HIGH) {limitSwitch1 = true;}

I can click on the status widget in the dashboard, which changes its state but I want the state to change when the limit switch is pressed.
I get nothing happening with the dash widget when the limit switch is pressed.
This is my code.

#include "thingProperties.h"
#include <Wire.h>
#include <DS3232RTC.h>
#include <SolarPosition.h>


DS3232RTC myRTC;

#define MOTOR_ON LOW
#define MOTOR_OFF HIGH

const uint8_t digits = 3;

SolarPosition Home(15.898551, 101.539774);  // Thailand
//SolarPosition Home(52.898551, -2.539774);  // Home//RTC CODE


const int azEncoder_a = 2;  // Green - pin 2 - Digital
const int azEncoder_b = 4;  // White - pin 4 - Digital
long azEncoder = 0;

const int elEncoder_a = 3;  // Green - pin 3 - Digital
const int elEncoder_b = 5;  // White - pin 5 - Digital
long elEncoder = 0;


const int azLimitSwitchPin = A0;  // DEFINE PIN TO USE FOR AZIMUTH LIMIT SWITCH
const int elLimitSwitchPin = A1;  // DEFINE PIN TO USE FOR AZIMUTH LIMIT SWITCH
const int azMotorPinPositive = 9;
const int azMotorPinNegative = 8;
const int elMotorPinPositive = 7;
const int elMotorPinNegative = 6;

bool nightime;
bool daytime;
bool trackerAzimuthRunning = false;
bool trackerElevationRunning = false;
bool sunRising = false;



int azLimitSwitch;  // VARIABLE TO HOLD THE ABOVE VALUE
int elLimitSwitch;

int hours;
int minutes;
int seconds;
int trackerAzimuthAngle;
int trackerElevationAngle;
int start = 0;
int azimuthSun_position;
float sunElevation;
float newPosition;
float oldPosition;
 

void setup() {
  Serial.begin(9600);
   initProperties();
   ArduinoCloud.begin(ArduinoIoTPreferredConnection);
   setDebugMessageLevel(2);
   ArduinoCloud.printDebugInfo();
  
  Wire.begin();
  pinMode(azEncoder_a, INPUT_PULLUP);
  pinMode(azEncoder_b, INPUT_PULLUP);

  pinMode(elEncoder_a, INPUT_PULLUP);
  pinMode(elEncoder_b, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(2), azEncoderPinChangeA, RISING);
  attachInterrupt(digitalPinToInterrupt(3), elEncoderPinChangeB, RISING);

  pinMode(azLimitSwitchPin, INPUT);  // LIMIT SWITCH
  pinMode(elLimitSwitchPin, INPUT);  // LIMIT SWITCH


  pinMode(azMotorPinPositive, OUTPUT);
  pinMode(azMotorPinNegative, OUTPUT);
  pinMode(elMotorPinPositive, OUTPUT);
  pinMode(elMotorPinNegative, OUTPUT);

  SolarPosition::setTimeProvider(myRTC.get);
}

void loop() {  
  ArduinoCloud.update();
  rtcCode();

 limitSwitch1 = digitalRead(A0);
  if(A0 == LOW){limitSwitch1 = false;}
  else if(A0 == HIGH) {limitSwitch1 = true;}

  trackerAzimuthAngle = azEncoder / 1.67;    //This change to degrees
  trackerElevationAngle = elEncoder / 1.67;  // 6This changes to degrees
  azLimitSwitch = digitalRead(azLimitSwitchPin);
  elLimitSwitch = digitalRead(elLimitSwitchPin);

  if (newPosition > oldPosition) {
    Serial.print("THE SUN IS GOING UP");
    Serial.print('\n');
    sunRising = true;
  }

  else if (newPosition < oldPosition) {
    Serial.print("THE SUN IS GOING DOWN");
    Serial.print('\n');
    sunRising = false;
  }
  oldPosition = newPosition;
  newPosition = sunElevation;


  Serial.print("AZIMUTH LIMIT SWITCH STATUS =.....");  //0 = Closed
  Serial.print(azLimitSwitch);
  Serial.print('\n');
  Serial.print("ELEVATION LIMIT SWITCH STATUS =.....");  // 0 = Closed
  Serial.print(elLimitSwitch);
  Serial.print('\n');

  if (start < 1) {
    homing();  // This statement checks to see if the programs has just started.
  }

  Serial.print("TRACKER AZIMUTH ANGLE IS   ");
  Serial.print(trackerAzimuthAngle);
  Serial.print('\n');

  Serial.print("TRACKER ELEVATION ANGLE IS   ");
  Serial.print(trackerElevationAngle);
  Serial.print('\n');

  //ADJUST THESE TIMES FOR TESTING
  if (hours >= 4 && hours <= 21 && minutes <= 59 && seconds <= 59) {
    daytime = true;
    nightime = false;
  } else {
    nightime = true;
    daytime = false;
  }
  Serial.print("DAYTIME  ");
  Serial.print(daytime);
  Serial.print('\n');
  Serial.print("NIGHTIME  ");
  Serial.print(nightime);
  Serial.print('\n');


  // CHANGE THE BELOW FOR TESTING
  if (daytime == true) {
    azimuthRunning();
  } else {
    Serial.print("PAUSED NOT MOVING UNTIL 6AM");
    Serial.print('\n');
    Serial.print('\n');

    digitalWrite(azMotorPinPositive, HIGH);
  }
  // CHECK TO SEE IF ITS TIME TO HOME POSITIONE
  if (hours == 17 && minutes == 47 && seconds == 0) {
    homing();
  }
}
void homing() {
  digitalWrite(azMotorPinNegative, MOTOR_OFF);
  digitalWrite(azMotorPinPositive, MOTOR_OFF);
  digitalWrite(elMotorPinNegative, MOTOR_OFF);
  digitalWrite(elMotorPinPositive, MOTOR_OFF);
  
 
  //HOMING AZIMUTH

  while (digitalRead(azLimitSwitchPin) == LOW) {
    Serial.print("HOMING AZIMUTH");
    Serial.print('\n');
    digitalWrite(azMotorPinNegative, MOTOR_ON);
      
  }
  digitalWrite(azMotorPinNegative, MOTOR_OFF);

  while (digitalRead(azLimitSwitchPin) == HIGH) {
    Serial.print("BACKING OFF AZIMUTH");  //Change this to move motor
    Serial.print('\n');
    digitalWrite(azMotorPinPositive, MOTOR_ON);
    
  }
  azEncoder = 0;  // Sets the encoder back to 0 once homed
  digitalWrite(azMotorPinPositive, MOTOR_OFF);

  //HOMING ELEVATION

  while (digitalRead(elLimitSwitchPin) == LOW) {
    Serial.print("HOMING ELEVATION");
    Serial.print('\n');
    digitalWrite(elMotorPinNegative, MOTOR_ON);
  }
  digitalWrite(elMotorPinNegative, MOTOR_OFF);

  while (digitalRead(elLimitSwitchPin) == HIGH) {
    Serial.print("BACKING OFF ELEVATION");  //Change this to move motor
    Serial.print('\n');
    digitalWrite(elMotorPinPositive, MOTOR_ON);
  }
  elEncoder = 0;  // Sets the encoder back to 0 once homed
  digitalWrite(elMotorPinPositive, MOTOR_OFF);
  start++;
}

void azimuthRunning() {

  if (azimuthSun_position > trackerAzimuthAngle && daytime == true && trackerElevationRunning == false) {
    trackerAzimuthRunning = true;
    digitalWrite(azMotorPinPositive, MOTOR_ON);
    Serial.print("AZ RUNNING ");

  } else {
    trackerAzimuthRunning = false;
    digitalWrite(azMotorPinPositive, MOTOR_OFF);
    Serial.print("AZ Waiting ");
    Serial.print('\n');
  }
  if (trackerAzimuthRunning == false) {
    elevationRunning();  //Elevation Running only gets called if azimuth is not running
  }
  Serial.print('\n');
  Serial.print('\n');
  Serial.print('\n');
}

void elevationRunning() {

  if (sunRising == true) {
    elevationUp();
  } else if (sunRising == false) {
    elevationDown();
  }
}

void elevationUp() {
  if (sunElevation > trackerElevationAngle && daytime == true) {
    trackerElevationRunning = true;
    digitalWrite(elMotorPinPositive, MOTOR_ON);
    Serial.print("EL RUNNING GOING UP ");
  }

  else {
    trackerElevationRunning = false;
    digitalWrite(elMotorPinPositive, MOTOR_OFF);
    Serial.print("EL WAITING");
  }
  Serial.print('\n');
}

void elevationDown() {
  if (sunElevation < trackerElevationAngle && daytime == true) {
    trackerElevationRunning = true;
    digitalWrite(elMotorPinNegative, MOTOR_ON);
    Serial.print("EL RUNNING GOING DOWN ");
  }

  else {
    trackerElevationRunning = false;
    digitalWrite(elMotorPinNegative, MOTOR_OFF);
    Serial.print("EL GOING DOWN WAITING");
  }
  Serial.print('\n');
}

void rtcCode() {
  printTime(myRTC.get());
  Serial.print(F("Home:\t"));
  printSolarPosition(Home.getSolarPosition(), digits);
}

void azEncoderPinChangeA() {
  azEncoder += digitalRead(azEncoder_a) == digitalRead(azEncoder_b) ? -1 : 1;
}
void elEncoderPinChangeB() {
  elEncoder += digitalRead(elEncoder_a) == digitalRead(elEncoder_b) ? 1 : -1;
}

void printSolarPosition(SolarPosition_t pos, int numDigits) {
  Serial.print(F("el: "));
  Serial.print(pos.elevation, numDigits);
  Serial.print(F(" deg\t"));

  Serial.print(F("az: "));
  Serial.print(pos.azimuth, numDigits);
  Serial.println(F(" deg"));
  azimuthSun_position = (pos.azimuth);
  sunElevation = (pos.elevation);
}

void printTime(time_t t) {
  tmElements_t someTime;
  breakTime(t, someTime);

  Serial.print(someTime.Hour);
  Serial.print(F(":"));
  Serial.print(someTime.Minute);
  Serial.print(F(":"));
  Serial.print(someTime.Second);
  Serial.print(F(" UTC on "));
  Serial.print(dayStr(someTime.Wday));
  Serial.print(F(", "));
  Serial.print(monthStr(someTime.Month));
  Serial.print(F(" "));
  Serial.print(someTime.Day);
  Serial.print(F(", "));
  Serial.println(tmYearToCalendar(someTime.Year));

  hours = someTime.Hour;
  minutes = someTime.Minute;
  seconds = someTime.Second;
}

Hi @mickh1

I see a couple of issues here:

  1. if(A0 == LOW)

In this if, A0 will never be HIGH or LOW. Instead, it's the value read from A0 which will be HIGH or LOW.
For this reason, I would read the value coming from the pin and assign it to another variable, e.g. int sensorValue

I would replace those 3 lines with something like this:

  int sensorValue = digitalRead(<insertPinNumberHere>);

  if (sensorValue == LOW) {
    limitSwitch1 = false;
  } else if(sensorValue == HIGH) {
    limitSwitch1 = true;
  }

  1. Please note, I've used a placeholder <insertPinNumberHere> because (if I'm not wrong) on some Arduino boards reading with digitalRead from an analog pin (like A0) could possibly not be working. For example on my Arduino Uno R4 WiFi it doesn't seem to work, but it could work on your board.

Let me know how if this helps.
You seem to be working on an interesting project, like an electronic "sun follower"?

Hi
Thanks for your help.
I have tried this and still get no change when the limit switch is pressed.
I have now changed the wiring so that the limit switch uses digital Pin 10 to establish if this was causing the issue.

This is the code now being used

int sensorValue = digitalRead(10);
  if(sensorValue == LOW){limitSwitch1 = false;}
  else if(sensorValue == HIGH) {limitSwitch1 = true;}

I have also found that I cannot use the Switch Widget or the Push Button Widget with a Boolean variable?

I now have this working with the above code.
However I have spent hours going over everything, changing code and getting nowhere to find out that the main issue I was having is the amount of "lag" with communication from the board to the cloud once a sketch is uploaded.
It can take up to 5 minutes before everything functions correctly.
This makes the widget dashboard not really useable.
Can you please suggest anything that may be causing this.

I have also got the board connected through USB C to rule out any Wifi issues.

You can use the Switch or Push Button widgets with booleans provided that your variable is NOT readonly, i.e. it's writeable.

I mean, when you use a Switch widget, you're supposed to control "actively" the underlying variable (i.e. you're writing a value) to do something like turning on or off a lightbulb.

Instead, if your variable is READONLY, you're reading a value that you can't control actively. You're just reading its value, e.g. if a light sensor is above a certain threshold because your sensor is in the daylight. But you cannot turn off the sun with a switch! :sunny: :smile:
So, eventually you can only read its value.

I hope this clarifies the intended usage of Switch and Push Button widgets.

Regarding lagging communications, usually, after the connection is established, the widgets react almost instantly. In my experience the initial connection can take a while (like 10 seconds) depending on a series of events:

  • what you're doing in the setup
  • initial connection with your WiFi router
  • connection with Arduino Cloud
  • security certificates exchange
  • general network conditions

I would say that 5 minutes is definitely not usual.

I'd suggest to increase the verbosity of the ArduinoCloud library changing the parameter from 2 to 4 in
setDebugMessageLevel(2);

This way you can understand if the issue is in the connection to Arduino Cloud or elsewhere.

That said, when using the ArduinoCloud library you have to make sure you're not blocking the loop() function with some blocking code.
I haven't tested your code, but I see some "while" conditions in the homing() function which could possibly block the execution?
I could be wrong, but I see a "while something is HIGH" and the a few line below "while something is LOW" which somehow seems a contradiction?

while (digitalRead(azLimitSwitchPin) == LOW) {
[...]
while (digitalRead(azLimitSwitchPin) == HIGH) {

But please note that I haven't tested you code.

Probably this sketch was originally not written to interact with the Cloud?

Ok thanks for your help.
The only reason I wanted to use the cloud was to be able to view data.
As "Serial Monitor" is not available over wifi thought this was a good option.
I think however that its going to be a steep curve trying to get this to work effectively over the cloud and haven't got the time to persevere with it.
So its going to be "Dig a trench and put a USB cable to the solar panels Lol".

From what I am reading online there also seems to be a lot of issues with the Uno R4 Wifi board so will probably go back to the R3 and save the R4 for another project.

I think that viewing your data without connecting your board via USB is a perfect use case for using the Cloud.
There are a few tutorials on how to use the Cloud to control a greenhouse, e.g. this one can be an interesting reading:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.