CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

serial communication over the air - missed events [Solved]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

serial communication over the air - missed events [Solved]
PostPosted: Sat Jun 13, 2020 3:29 pm     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jun 13, 2020 5:55 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 12:10 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 1:37 am     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 4:33 am     Reply with quote

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: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 6:31 am     Reply with quote

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: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 4:25 pm     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 4:56 pm     Reply with quote

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: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 14, 2020 5:04 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 12:11 am     Reply with quote

Ugh!....

At least you have an 'answer', but it does make the point about such clone
modules... Sad

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... Sad
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: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:12 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:13 am     Reply with quote

You don't mention the aluminium foil hat....
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:17 am     Reply with quote

I'm completely bald, so I just wrapped it around my head :-)
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:25 am     Reply with quote

So long as you didn't try to attach it with a meat skewer, that should be fine.
Very Happy
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:36 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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