I would like to use 433 RF modules for a project, in which I will need to send a message from an arduino to another to trigger a behaviour. This happens rather regularly and fast, and I would love to be able to see if there are "lost" in a sequence.
I did a piece of code in order to send a ascendent progression of numbers. This will allow me to see if there are missing steps, but I am doing something wrong and I am not seeing numeric values in my serial print.
In transmitter: msg is defined as a single char and it is defined as "null". Not good. Then you will transmit a number of control chars like newline, cariage return, Tab etc. When will You stop that msg++?
Use an array filled with the alphabet and cut off at the end and don't transmit unknown garbage following the arrary.
This is a bit put of my scope. I am an artists who tries to apply technology the art pieces, and I do not really have programming skills. I am mostly copying and pasting.
If you wish to help me sort this out in a more practical weay, I would really appreciate it.
camilozk:
I would like to use 433 RF modules for a project, in which I will need to send a message from an arduino to another to trigger a behaviour. This happens rather regularly and fast
So why have you chosen to use the 433 RF modules, and I am guessing you mean those real cheap OOK\AFSK modules.
Is it because they are cheap ?
Does the messaging need to be reliable and robust as well ?
I would like to use 433 RF modules for a project, in which I will need to send a message from an arduino to another to trigger a behaviour. This happens rather regularly and fast.
I am an artists who tries to apply technology the art pieces, and I do not really have programming skills
Can you please explain more about your project. How far apart are the Arduino's?
What information is going between them? What does "fast" mean.
The bigger picture will get you better help. As @srnet suggests, there may be better wireless solutions than the ook/ask modules.
camilozk:
This is a bit put of my scope. I am an artists who tries to apply technology the art pieces, and I do not really have programming skills. I am mostly copying and pasting.
If you wish to help me sort this out in a more practical weay, I would really appreciate it.
Have a close look at the RH library examples, and don't modify them beyond necessity if you don't know what you're doing. Part of the reason they exist is to allow people who don't really understand all the functions, to get started right away.
"Fast" means, I am expecting to send a message each 30ms.
The message is always the same message: "ping", and I simply use this message to trigger a behaviour. It would be any message, but it is important that I dont loose messages on the way. That is why I wanted to create this sketch, where I send a numeric value in ascendent order, to see if I get all the numbers consecutively.
I hope I am providing enough info to take a look at this
The issue with the posted code is that it is sending the number as a binary value and receiving it as an ASCII encoded string. I believe the following code does what you intended.
#include <RH_ASK.h>
RH_ASK driver;
int last_idx = 0;
void setup()
{
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init failed");
}
void loop()
{
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(buf);
if (driver.recv(buf, &buflen)) // Non-blocking
{
// Message with a good checksum received, dump it.
buf[buflen]=0;
Serial.print("Received(");
Serial.print(buflen);
Serial.print(",");
int idx=atoi(buf);
Serial.print(idx>last_idx ? "+" : "-");
Serial.print(idx-last_idx);
last_idx=idx;
Serial.print("}: ");
driver.printBuffer(buf, buf, buflen);
}
}
You'll probably find that there are dropped messages. No radio communications protocol is immune to this, but this one is "send and forget", that is, there is no acknowledgement from the remote node that it has received a message.
If you could describe your overall project we might be able to give more focused advice.
I actually wanted to have a code in which I can observe if there are dropped messages. This is why:
I have two arduinos controlling a led strip. If I simply program them to have the same behaviour and I turn them both on at the same time, after some time they will not be in synchro anymore. I believe this is simply because the processors work in slightly different speeds, and after some time they simply loose the synchro.
The idea of having an RF module to synchronise them, is that one of the boards is writing in the led strip a line of information and sending a message to the second board to also write a line of information. The second board will then only "behave" if it receives an instruction from the first one to do so. If there are dropped messages, they will also after some time loose their synchro
The system is part of a light installation that I move from festival to festival. Normally is set in parks, squares or open streets, so no walls in between, but perhaps some trees.
From your suggestions, I see that it will be a bit more costly that what I was expecting, but this shouldnt be a big deal. The real question: are they easy to implement?
If all you need is time synch, why bother with RF? Just equip each unit with an RTC. Then they will always be in time synch. You can synch everything once when you set up an installation, the drift will probably be negligible for the length of time it will be on exhibit (perhaps you could tell us how long that is...). Then distance and/or obstacles and/or interference are a complete non-problem and everything is cheaper and simpler.
Can you give us an idea of the time synchronization required. You originally talked of a 30 ms heartbeat. Do you just need to synchronize the start of a routine, or do you need to stay in some sort of close synch through the routine. How long are the light shows?
If you only need one second synchronization, there are probably rtc solutions. I have seen some information that it may be possible to initialize and synch multiplte rtcs at the same time on the i2c bus with good results, i.e. better than one second synchronization.
Yes, at least the DS3231 RTC clears all its subsecond counters when the time is set. So subsequent seconds readouts will have subsecond accuracy until the drift sets in. Another way is to equip each unit with a GPS receiver to get the exact time (but that method has its own pitfalls).
cattledog:
Can you give us an idea of the time synchronization required.
I am displaying light patterns with led strips at a rate of 30 frames per second. Normally, not having any kind of synchronisation, when I start the different systems at the same time, after some minutes (15, 20 minutes) they are already out of synchro. This is very inconvenient since the installations are normally working every night during several days in each different location.
So the idea is: first arduino writes a frame in the led strip, and send a signal to the second arduino. the second arduino only writes a line when a signal is received. If there are missing signals, this would also affect synchronisation in the long run.
I somehow still have the felling that sending a signal after each frame is written is the best synchronization method here. I like the recommendation done in #9 (RF 69HW / Adafruit Feather / Anarduino / Moteino) although they are costly...
I am thinking of ways to keep this simple for you.
First, can you tell us how you trigger the frames in the current program? How are the frames themselves coded? Do you ever use delay()? Do you know if the loss of synchronization is due to the slightly different running times of each frame, or the shifting of trigger time independent of the frame running?
I am displaying light patterns with led strips at a rate of 30 frames per second. Normally, not having any kind of synchronisation, when I start the different systems at the same time, after some minutes (15, 20 minutes) they are already out of synchro. This is very inconvenient since the installations are normally working every night during several days in each different location.
Do you know how many frames offset it takes to create a problem?
Do you currently have Arduino's which you are using? What model?
My first thought would be that an Arduino with a crystal oscillator (not the ceramic resonator) might be good enough to stay in sync.
Leonardo and Micro have a 16Mhz crystal oscillator. Some uno clones have a cyrstal oscillator instead of the resonator. You need to look at the images and consult with vendors.
There are custom "uno" boards like the Freeduino, Ruggeduino, and mega 1284 based boards with crystal oscillators.
A second approach would be to use the DS3231 as a clock source. I would use the square wave output set for 1024 Khz, count the pulses with an interrupt, and trigger the frame every time the count went to 34. This will provide a more stable trigger than using millis() or micros() based on the internal clock.
Finally, there is the master/slave approach with the wireless trigger which we have been discussing.
Do you have a video of your light shows you can link? Especially one which shows the in and out of sync performance. This sounds like an interesting project.
camilozk:
I am displaying light patterns with led strips at a rate of 30 frames per second. Normally, not having any kind of synchronisation, when I start the different systems at the same time, after some minutes (15, 20 minutes) they are already out of synchro. This is very inconvenient since the installations are normally working every night during several days in each different location.
So the idea is: first arduino writes a frame in the led strip, and send a signal to the second arduino. the second arduino only writes a line when a signal is received. If there are missing signals, this would also affect synchronisation in the long run.
I somehow still have the felling that sending a signal after each frame is written is the best synchronization method here. I like the recommendation done in #9 (RF 69HW / Adafruit Feather / Anarduino / Moteino) although they are costly...
If I understand correctly, you've tried a solution where each node is preprogrammed with the light sequence, they're started at the same time, and then drift out of sync over some period.
From this baseline, the options are 1) better timekeeping on each node (as some have suggested above) or 2) somehow bringing them back into sync periodically. If you keep the original approach, but have a master node transmit a sync message periodically, say once per second, and use that to correct slave node's time drift, that would keep them in sync.
The slave nodes would expect a sync once per second, so upon receiving one, it could check the interval since the last one to recognize that it has missed one or more. The advantage over the originally proposed scheme is that missed messages don't matter much as long as it gets one every minute or so.