Go Down

Topic: Arduino Uno to Arduino Nano RS485: Setting a variable (Read 1 time) previous topic - next topic

jfrech14

I am working on a high voltage regulation system where I will have 1000 of these bases connected to a few hubs. I have the electronics sorted out and I understand how to assign each Nano its own address. However, because of the sensitivity of the devices attached and the inability to access any of the boards while one, changing variables in the Arduino IDE and having the board reset isn't an option.

The plan is to use RS485 to read the high voltage every so often and impose an interrupt that will allow us to change the set point, which is just a variable. Another task is to do the same thing to turn on or off a logic gate, but if I can figure out setting the variable, I assume changing the pin state from "high" to "low" will be a similar process. As of right now, I have to have either the IDE serial monitor or my python program running (to monitor the high voltage) from the beginning or else it resets the board (can't have it). For the logic gate, I am just using a jumper which needs to be put into code because there is no access to the boards once everything is up and running. For the variable setting I am just stuck to changing it in the IDE. So literally any help will get me somewhere on these three issues.

My questions:

1) Is it possible, on this board and the bootloader written in the IDE, to change the variable outside of the Arduino IDE through RS485 that will not reset the board? (Having 1200V unmonitored and connected to expensive equipment is a no-no says the boss lol)

2) If so, how do I find the particular address(s) of the variable(s) I want to change within the code (do I have to assign it?)?

3) Will I have to forego using the bootloader and burn the program in or write it all in C without the IDE?

4) Will it be easier to do the code in the IDE and the RS485 communication in another language like Python?


To clarify: I did google this first, I am a physicist and not a computer/electrical engineer, and I don't expect you to do the code for me. I would just like to be pointed in the right direction  :)

Thanks for any help/advice you can offer!
Josh

chucktodd

I am working on a high voltage regulation system where I will have 1000 of these bases connected to a few hubs. I have the electronics sorted out and I understand how to assign each Nano its own address. However, because of the sensitivity of the devices attached and the inability to access any of the boards while one, changing variables in the Arduino IDE and having the board reset isn't an option.

The plan is to use RS485 to read the high voltage every so often and impose an interrupt that will allow us to change the set point, which is just a variable. Another task is to do the same thing to turn on or off a logic gate, but if I can figure out setting the variable, I assume changing the pin state from "high" to "low" will be a similar process. As of right now, I have to have either the IDE serial monitor or my python program running (to monitor the high voltage) from the beginning or else it resets the board (can't have it). For the logic gate, I am just using a jumper which needs to be put into code because there is no access to the boards once everything is up and running. For the variable setting I am just stuck to changing it in the IDE. So literally any help will get me somewhere on these three issues.

My questions:

1) Is it possible, on this board and the bootloader written in the IDE, to change the variable outside of the Arduino IDE through RS485 that will not reset the board? (Having 1200V unmonitored and connected to expensive equipment is a no-no says the boss lol)

2) If so, how do I find the particular address(s) of the variable(s) I want to change within the code (do I have to assign it?)?

3) Will I have to forego using the bootloader and burn the program in or write it all in C without the IDE?

4) Will it be easier to do the code in the IDE and the RS485 communication in another language like Python?


To clarify: I did google this first, I am a physicist and not a computer/electrical engineer, and I don't expect you to do the code for me. I would just like to be pointed in the right direction  :)

Thanks for any help/advice you can offer!
Josh
Do a search on the ICSC RS485.  MajenkoLibraries ICSC It is an Arduino library that does packet based communications.  You would implement this library to transport your messages all of the slaves would listen (each RS485 Bus is limited to 32 nodes) Linear Technology RS485 reference

check out MODBUS protocol.

Chuck.
Currently built mega http server, Now converting it to ESP32.

jfrech14

Do you happen to know if the ICSC process has to be in the loop or can I change a pin state in the setup. I don't want to constantly poll or set the digital pin. I pretty much just want to change the variable or logic gate state once and let it run. Then if I need to change the logic gate state I can just change the code in the master.

Also, if I need to actively change these and I reload the changed code to the master, what happens to the slave? Will it restart as well?(doesn't really make sense that it would but better ask than find out)
Or will just the master restart and the slave will respond accordingly once the master is back up and running? I have the code up on the slave but left my other Arduino at home so can't test it until tomorrow or Friday. Thanks for pointing me towards Majenko! It looks like it will likely be the solution. Depends on the answers to the above questions haha :)

Cheers,
Josh

chucktodd

Do you happen to know if the ICSC process has to be in the loop or can I change a pin state in the setup. I don't want to constantly poll or set the digital pin. I pretty much just want to change the variable or logic gate state once and let it run. Then if I need to change the logic gate state I can just change the code in the master.

Also, if I need to actively change these and I reload the changed code to the master, what happens to the slave? Will it restart as well?(doesn't really make sense that it would but better ask than find out)
Or will just the master restart and the slave will respond accordingly once the master is back up and running? I have the code up on the slave but left my other Arduino at home so can't test it until tomorrow or Friday. Thanks for pointing me towards Majenko! It looks like it will likely be the solution. Depends on the answers to the above questions haha :)

Cheers,
Josh
Code: [Select]

#include <ICSC.h>

void pinger(unsigned char station, char command, unsigned char len, char *data)
{
  static unsigned char led = 0;
  
  digitalWrite(13, led);
  led = 1-led;
}

void setup()
{
  ICSC.begin(1, 115200);
  pinMode(13, OUTPUT);
  ICSC.registerCommand(ICSC_SYS_PONG, &pinger);
}

void loop()
{
  static unsigned long ts = millis();
  
  if (millis() - ts >= 1000) {
    ts = millis();
    ICSC.send(2, ICSC_SYS_PING, 5, "PING");
  }
  ICSC.process();
}


Josh, this is an example of ICSC,  In loop() It sends out a message ICSC_SYS_PING  to terminal 2, with a 5 character data packet.
In setup() it registers a callback to responded to message ICSC_SYS_PONG by blinking the LED on Pin 13.

Yes, in loop() ICSC.process() must be called.


The 'slave' code callback is activated everytime the 'slave' receives a message with the correct Message ID.  

You will have to decide how you want your Arduinos to respond.  With your vague description; I would create 'slave' code that:
  • on boot, 'safes' the hardware
  • waits for commands from the 'master'
    each message could do a specific task
    either respond with a status
    or change a global value
  • have a lost command timer that starts yelling 'I can't Hear YOU!'
    and starts shutting down the attached hardware after so many missed heartbeat pings


the master could be controlled thru some UI.  There is no reason to reprogram the master to just change a value in the slaves.  


Chuck.
Currently built mega http server, Now converting it to ESP32.

jfrech14

Thanks for your response!

By reprogramming the master to change a value in the slave I mean that I need to change a variable on the slave remotely a single time. For instance on the slave I have the integer HVset which tells the feedback loop what the set voltage is. I need to change that variable a single time via the master. The slaves will be in an area of EXTREMELY high radiation and will not be able to be accessed while in operation or even for a while after the experiment is stopped. So from a remote location, I have to change the voltage set point, change the state of a pin that goes to a logic gate, and read the voltage from an I2C ADC. That is why I was saying I would need to upload a new code to the master because I need to change the values every now and then. So, it would be best if I could change a variable that is defined in the setup function, but I can work with it being in the loop function. If there are other ways to accomplish it, then I am all ears!

chucktodd

Thanks for your response!

By reprogramming the master to change a value in the slave I mean that I need to change a variable on the slave remotely a single time. For instance on the slave I have the integer HVset which tells the feedback loop what the set voltage is. I need to change that variable a single time via the master. The slaves will be in an area of EXTREMELY high radiation and will not be able to be accessed while in operation or even for a while after the experiment is stopped. So from a remote location, I have to change the voltage set point, change the state of a pin that goes to a logic gate, and read the voltage from an I2C ADC. That is why I was saying I would need to upload a new code to the master because I need to change the values every now and then. So, it would be best if I could change a variable that is defined in the setup function, but I can work with it being in the loop function. If there are other ways to accomplish it, then I am all ears!
The setup() function is only executed once per boot/power cycle.  the Arduino has 1024 bytes of user accessible EEPROM in the CPU.  you could update an EEPROM location and during the boot process load that value.

I don't know how RAD hardened AVR processors are?

You are going to have to decide when your updates are applied. 

I would save config data into the internal EEPROM with some sort of checksum/ECC coding.  Your boot process should do some power on self tests with software validation.

You have not described the failure modes or the effects of uncontrolled operation.

I would have the slaves not act unless they are under control of the master. 

If they have to act independent of the master to control some feedback, you must verify your 'config' data is valid and within range.

Chuck.
Currently built mega http server, Now converting it to ESP32.

jfrech14

I have an arduino uno in the accelerator hall right now waiting for the beam to begin. I have a program that will fill up as much of the flash as I can and have it read back the values to check for errors. It should be shielded from high energy particles but will be in a bath of neutrons, so we will see. So from what I gather, I can either have the set point being checked every check and can just change it in the loop() function for real time changes, or more appropriately just communicate with the logic hate (which turns off the high voltage) and upload a new sketch to the slave that has the changes I desire. If the first option is possible, that is likely the route to go. Cabling for 1000 of these bases is going to be crazy so adding in a USB to upload sketches is not ideal. The bases for the detectors will be behind a lead glass wall essentially. That board has some digital electronics, but the board with the arduino will likely be placed behind a shield 30-50 feet away next to the data acquisition computer. Then all of the data is monitored from outside of the hall. Everything is so irradiated that if it fails, you're screwed for a while. The idea is to keep the board up and running the entire time. So, I guess it is that route.

Thanks again for the help thus far!

jfrech14

And to elaborate more:

I have a 1200V signal being knocked down to a 12bit ADC which is constantly being monitored and compared the HVset. This is the basis for my feedback control. I need to on the fly change HVset and from what you said, it seems like the only way to do that is by checking the status of HVset each cycle in the loop() function and just changing that value from the master. This should ideally be placed first in the loop() function so that everything in my feedback is using the same HVset. This seems like it will slow down my system, but at this stage that isn't a big deal.

Then, if I want to turn off the high voltage I can just send the pin low from the master and the same will happen as before, but for the pin.

The ADC readout needs to happen every cycle anyway so all is well with that.

The other points you made are good and should be implemented in future stages. The idea is to have constant control and monitoring. If communication with the master is broken, the high voltage should remain the same, but that might not be ideal. So what I think you're saying is if I lose communication, set the logic gate low to turn off the high voltage. The arduinos will be powered externally by 5 or 12V (haven't decided) so even if this emergency sequence is started, I will be able to remotely start it again once communication is re-established. Again, physically doing things is pretty much not an option for weeks or months at a time I believe. So everything must be remote. This is the first time I've taken on such a task so it's interesting.

chucktodd

And to elaborate more:

I have a 1200V signal being knocked down to a 12bit ADC which is constantly being monitored and compared the HVset. This is the basis for my feedback control. I need to on the fly change HVset and from what you said, it seems like the only way to do that is by checking the status of HVset each cycle in the loop() function and just changing that value from the master. This should ideally be placed first in the loop() function so that everything in my feedback is using the same HVset. This seems like it will slow down my system, but at this stage that isn't a big deal.

Then, if I want to turn off the high voltage I can just send the pin low from the master and the same will happen as before, but for the pin.

The ADC readout needs to happen every cycle anyway so all is well with that.

The other points you made are good and should be implemented in future stages. The idea is to have constant control and monitoring. If communication with the master is broken, the high voltage should remain the same, but that might not be ideal. So what I think you're saying is if I lose communication, set the logic gate low to turn off the high voltage. The arduinos will be powered externally by 5 or 12V (haven't decided) so even if this emergency sequence is started, I will be able to remotely start it again once communication is re-established. Again, physically doing things is pretty much not an option for weeks or months at a time I believe. So everything must be remote. This is the first time I've taken on such a task so it's interesting.
if you are going to need 1000's of slave devices, you are going to have to break them up into smaller groups.  Standard RS485 is designed to support 32 devices on a net.  There are more efficient transceivers sometimes called "1/8 load" that would allow you to connect 256 devices on a net.  

You might also want to look into WDT (watch dog timeout reset). The WDT function may possibly recover a 'locked up' Arduino.

WDT Turtorial from University of South Florida

Sounds like you have a fun project.

Chuck.
Currently built mega http server, Now converting it to ESP32.

Go Up