|
|
View previous topic :: View next topic |
Author |
Message |
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
serial communication over the air - missed events [Solved] |
Posted: Sat Jun 13, 2020 3:29 pm |
|
|
Dear Sirs,
I have a board that waits for a press of a button. When that happens, it sends a string over UART to HC-12 unit, which sends it over the air to another HC-12 unit, where the second board receives the message over UART. The second board then sends back confirmation message. My problem is that every now and then (once in every 50, 60 presses, but no rule here) the second board misses the message. I'd be happy to hear any idea how to prevent those misses or rather, how to be 100% sure that the message was received by the second board. Both boards are maybe 2 meters apart, baud rate is 9.600 and key presses are happening slowly, every 5s or so. In real life it will be even slower.
Regards,
Samo |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat Jun 13, 2020 5:55 pm |
|
|
For testing purposes I would remove the HC12 units and connect the two PIC UART pins with twisted wires( be sure to have a ground between them !).
Run your program and press the button. If it works 100% , then you know the problem is related to the HC12 modules, perhaps configuration, antenna layout, ???
If the problem contiues then it is NOT the HC12 modules, suggesting some code problem, maybe timing, maybe buffering, maybe not having 'errors' in the #use rs232(...options) or ???
I can't say exactly what the problem is, but you should be able to eliminate or isolate 'sections' of code or hardware to narrow down where it is.
Do both PICs have xtals/caps for their clocks ?? For any serial communications it is critical that the PIC clocks be accurate. If using internal RC oscillators, it is possible one is slightly slow(say -1%), the other slightly fast(say +1.5%). That is a 2.5% difference and it might be enough to be a problem. When using serial they 'generally' will be OK if within 3% but that's NOT a hard and fast rule.
If possible eliminate all unnecessary code and post the program... maybe something will be seen by 'fresh eyes'.
Jay |
|
|
hmmpic
Joined: 09 Mar 2010 Posts: 314 Location: Denmark
|
|
Posted: Sun Jun 14, 2020 12:10 am |
|
|
If the HC12 module is not from the real source http://www.hc01.com then it can be the problem!
Many fake and poor module at ali and ebay. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sun Jun 14, 2020 1:37 am |
|
|
Lets whizz through some things:
First, as hmmpic says, there are a number of 'clone' HC12 modules around
of 'varying' quality. Some are 'famously bad'....
Then many of the modules arrive with their transmit power set to levels
that may well be illegal. In the UK for example, the maximum on the
433Mhz band without license, is 10mW. Many of the units arrive set to
20mW.
Now I can hear you thinking 'great extra range', but in fact the higher
power can often cause problems when the units are close to one another.
It may well be that the receiver is running right on it's maximum levels
and occasionally getting swamped....
Then any form of radio communication will have issues at times. It doesn't
take much. Perhaps a neighbour using a 433MHz transceiver, for the
link to momentarily be lost.The units are very good. Perhaps 99.9%
reliable, but still not 100%. This is why things like remote controls always
send duplicate data, to help ensure the message does get through.
You need to design your comms, so that perhaps the transmitter sends
the data with an 'ID', and the slave sends the ID 'back' when it is received.
Then on the master, if the ID reply is not seen in a few seconds, a
re-transmission is performed.
I see you are already sending back a confirmation, so just add code to
re-transmit if this is not seen.
Then reliability of the units is very dependant on the power supply. Good
reservoir/decoupling capacitor close to the module, and a nice stable
supply. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Jun 14, 2020 4:33 am |
|
|
Mr T's right again.....yeesh 2 meters is maybe 6' on this side of the pond , say 'arms stretched out' distance. it makes sense that the front end is being 'swamped', overloaded, as even 10mw RF is a LOT of energy at that distance.
It might even be RF getting into the PIC by an unused I/O pin,set an input it could become another antenna.
I'd config the HC12s for minimal power output and run the test again.
jay |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sun Jun 14, 2020 6:31 am |
|
|
First, thank you all for the answers. Below you'll find the transmit and receive code. The more I look at it, the more wrong and unreliable it seems :-). That is why I want to do it from scratch. I do set the power to minimum level and comm speed to "slow". Maybe the way to go is to send my message 10 times in a row an the receiver needs to see it at least twice in a time period? Maybe confirmation message isn't even needed in that case? As I said, I have tons of time between two events.
transmit:
Code: |
while(TRUE){
Reset_Counter = 0;
if(ENTER_switch_is_down){ // game button was pressed
delay_cycles(1);
ENTER_switch_is_down = FALSE;
Stop_Blinking = 1; // prevent blinks in TMR0 interrupt
output_low(LED); // turn LED on when button is pressed
Clear_UART_Buffer();
UART1_Send(GAME); // send game alert
Game_Counter++;
Confirmation_Timeout_Counter = 0;
while(!Confirmation_Message){ // wait till receiver signals it got the message
delay_ms(2);
Confirmation_Timeout_Counter++;
if(Confirmation_Timeout_Counter > 200){ // no confirmation,
UART1_Send(REPEAT_SEND); // send "RETRY" message
delay_cycles(1);
Retry_Counter++;
}
}
Confirmation_Message = 0;
Confirmation_Counter++;
delay_ms(500);
output_high(LED);
Stop_Blinking = 0;
} // IF(ENTER SWITCH...)
} // WHILE TRUE
|
receive:
Code: |
while(TRUE){
restart_wdt();
// got game message
if(Game_Completed_Message){
Game_Completed_Message = 0;
Game_Counter++;
OLED_gotoxy(10,1);
printf(OLED_putc,"%5lu ",Game_Counter);
UART1_Send(GOT_IT); // send confirmation message to HC-12 transmitter
output_low(GAME_LED); // blink LED
delay_ms(200);
output_high(GAME_LED);
// send message over LAN
// sensor output is formatted: GAME;NUMBER OF PLAYERS; FALLEN NUMBER DETECTED
fputs( "GAME;-1;-1",PORT2); // send to TCP-USR232
}
// transmitter didn't get the confirmation and sent repeat message, don't count this as a game
if(Game_Repeated_Message){
Game_Repeated_Message = 0;
Repeat_Counter++;
OLED_gotoxy(10,2);
printf(OLED_putc,"%5lu ",Repeat_Counter);
UART1_Send(GOT_IT); // send confirmation message to HC-12 transmitter again
}
}
|
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sun Jun 14, 2020 4:25 pm |
|
|
So I rewrote the thing. Transmitter sends 10 times, receiver has to see it at least three times. No confirmations. For the first 1.000 presses none was missed. But it is interesting. The number of detections vary from 6 to 10.
receiver:
Code: |
while(TRUE){
restart_wdt();
// scan the data coming in for half a second after the first detection of GAME message
// we should see the message at least three times
switch (DETECT_GAME){
// ****************************************************************************
// DETECT FIRST OCCURANCE OF THE MESSAGE
case IDLE:{
if(Game_Completed_Message){
Game_Completed_Message = 0;
Game_Detect_Counter++;
Timer = 0;
DETECT_GAME = DETECTING;
}
break;
}
// ****************************************************************************
// SAMPLE FOR HALF A SECOND AND COUNT DETECTIONS
case DETECTING:{
if(Game_Completed_Message){
Game_Completed_Message = 0;
Game_Detect_Counter++;
}
delay_ms(10);
Timer++;
if(Timer > 50){
Timer = 0;
DETECT_GAME = COUNTING;
}
break;
}
// ****************************************************************************
// SEE IF THE MESSAGE WAS DETECTED AT LEAST THREE TIMES IN HALF A SECOND
case COUNTING:{
if(Game_Detect_Counter > 2){
output_low(GAME_LED);
Game_Counter++;
OLED_gotoxy(10,1);
printf(OLED_putc,"%5lu ",Game_Counter);
// send message over LAN
// sensor output is formatted: GAME;NUMBER OF PLAYERS; FALLEN NUMBER DETECTED
fputs( "GAME;-1;-1",PORT2); // send to TCP-USR232
delay_ms(200);
output_high(GAME_LED);
}
else{ // less than 3 out of ten
Fail_Counter++;
OLED_gotoxy(10,3); // display number of fails
printf(OLED_putc,"%5lu ",Fail_Counter);
}
OLED_gotoxy(10,2); // display number of detections out of ten
printf(OLED_putc,"%5lu ",Game_Detect_Counter);
Game_Detect_Counter = 0;
DETECT_GAME = IDLE;
break;
}
// *************************** END SWITCH *************************************
} // switch brace
} // WHILE true
|
transmitter:
Code: |
// send the game info
while(TRUE){
Reset_Counter = 0;
switch (SEND_INFO) { // state machine for sending game
// ****************************************************************************
case WAIT_BUTTON:{
if(ENTER_switch_is_down){ // game button was pressed
ENTER_switch_is_down = FALSE;
Stop_Blinking = 1; // prevent blinks in TMR0 interrupt
while(input_state(ENTER_Switch) == 0){
output_low(LED); // turn LED on while the button is pressed
}
output_high(LED);
Game_Counter++;
SEND_INFO = SEND_GAME; // button was pressed, proceed to sending game info
}
break;
}
// ****************************************************************************
case SEND_GAME:{
// send the message 10 times. It takes about 270ms to do it.
output_toggle(LED);
UART1_Send(GAME); // send game alert
Retry_Counter++;
// at 9600bps each character takes 1,04ms. We are sending 6 characters, so cca. 7ms
delay_ms(20);
if(Retry_Counter >= 10){
Retry_Counter = 0; // preload counter
Stop_Blinking = 0; // enable blinks in TMR0 interrupt
SEND_INFO = WAIT_BUTTON;
}
break;
}
// ****************************************************************************
} // switch brace
} // WHILE TRUE
|
Thank you all. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Jun 14, 2020 4:56 pm |
|
|
While you have it 'working....' I would still , bypass the HC12s, use hardwire and run your test program.
You should get 100% .... if not, there's some 'quirky' code issue and not an HC12 problem. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sun Jun 14, 2020 5:04 pm |
|
|
All modules that I have are Chinese clones, different batches.
After another hour of testing: paired modules from the same batch work 100%, if they are mixed, errors creep in. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jun 15, 2020 12:11 am |
|
|
Ugh!....
At least you have an 'answer', but it does make the point about such clone
modules...
This post talks about exactly the same problem:
<https://hackaday.com/2018/05/05/fail-of-the-week-never-assume-all-crystals-are-born-equal/>
and the link from here:
<https://www.rictech.nz/products/25/GENUINE-HC-12-RF-Module>
It's down to the batch tolerances on the crystals used on the modules.
The genuine modules actually have very good tight frequency tolerances.
The 'clone' modules seem to have batches that are about 37KHz off
frequency. Just enough to cause issues...
This actually takes them outside the legal range for approval in Europe,
(and since this is an ITU spec, probably most other places), so a big
'caveat' on using the clone modules.... |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Jun 15, 2020 2:12 am |
|
|
So far 120.000 transmissions without an error :-). I read that article about crystals.
Yeah, I know Aliexpress stuff comes without any warranty. But I did put an SPF 2000 sunscreen on while testing. And a pair of welding goggles :-). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jun 15, 2020 2:13 am |
|
|
You don't mention the aluminium foil hat.... |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Jun 15, 2020 2:17 am |
|
|
I'm completely bald, so I just wrapped it around my head :-) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jun 15, 2020 2:25 am |
|
|
So long as you didn't try to attach it with a meat skewer, that should be fine.
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Jun 15, 2020 2:36 am |
|
|
No, being a hobby programmer/hardware developer and my own guinea pig, I used flux to glue it on :-). Fastened with some obsolete DIP 18f252 Pics under ears. It won't go anywhere. There are some sparks, but what can you do. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|