Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 02:08 04 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : How to learn RF remote codes?

     Page 4 of 5    
Author Message
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 06:42am 14 Mar 2018
Copy link to clipboard 
Print this post

Yes, from what I could see, the very first data packet was corrupted. But the subsequent ones were not.

I'm glad it makes sense to you!
Smoke makes things work. When the smoke gets out, it stops!
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 1000
Posted: 11:15am 14 Mar 2018
Copy link to clipboard 
Print this post

  TassyJim said  
When I want to do small timing intervals, I make my own high precision timer.
Set a PWM output to 100kHz and feed that output into one of the counting pins. Read the counting pin as required and you have 10 uS resolution.
You still have the problem of program execution time but this UNTESTED test program is the way I would try first up.

  Quote   DIM tick AS INTEGER, tock AS INTEGER
DIM code$
PWM 1, 100000, 50 ' this is out high resolution timer whch gets connected to pin 15
SETPIN 15, CIN
SETPIN 16, INTB, blip ' triggers on a high or low transition

DO
IF INKEY<>"" THEN
PRINT code$
ENDIF
LOOP

END

SUB blip
tick =
PIN(15)
IF PIN(16) = 1 THEN ' we went from low to high
tock = tick
ELSE ' we went from high to low
IF tick - tock > 40 THEN ' 400 uS is longer than a short interval so must be a "1"
code$ = code$ + "1"
ELSE
code$ = code$ +
"0"
ENDIF
'PRINT code$ ' printing will slow things down far too much
ENDIF
END SUB

Assuming a 28 pin micromite,
Connect pin 4 (PWM 1A output) to pin 15 counting input.
Connect your signal to pin 16


Jim


Hi Jim,
Thanks for this clever idea/tip. I have used it to decode a remote temperature/humidity sensor from Bangood . It was in the too hard basket but this gave me inspiration and I have cracked the decoding of it. I will start another thread about it so as not to hijack Grogster's thread any further.

thanks
Gerry




Latest F4 Latest H7 FotS
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 06:38am 16 Mar 2018
Copy link to clipboard 
Print this post

Grogster,
Can you try this code generator and see if it matches your devices.
It runs on a MX170 with the Tx pin on pin 16 but can be any.
  Quote   OPTION EXPLICIT
OPTION DEFAULT NONE

DIM INTEGER xmitpin = 16 ' the pin connected to the 433mhz module data pin
DIM FLOAT lengths(68)
DIM FLOAT noise(255)

DIM STRING testkey
DIM INTEGER testVal
DIM INTEGER n
FOR n = 0 TO 255
noise(n) =
RND()*500+20 ' fill noise array
NEXT n
PIN(xmitpin)=0 ' set the data pin low
SETPIN xmitpin, DOUT ' set it as an output

'*************** Main Loop ***************
DO
testkey =
INKEY$
IF testkey <>"" THEN
testval =
VAL(testkey)
PRINT testval
sendit(testval)
END IF
LOOP
END
' *********** END ***************************
SUB sendit(code AS INTEGER)
LOCAL FLOAT pulselength=295 ' us for the short pulse length Long is 3 times this
LOCAL INTEGER repeat=3 'number of times to repeat the transmission
LOCAL STRING senddata$ 'string containg the binary data

IF code >= 0 AND code <10 THEN
SELECT CASE code
CASE 0
senddata$ =
"011101010001110000000010"
CASE 1
senddata$ =
"011101010001110000000010"
CASE 2
senddata$ =
"011101010001110000000010"
CASE 3
senddata$ =
"011101010001110000000010"
CASE 4
senddata$ =
"011101010001110000000010"
CASE 5
senddata$ =
"011101010001110000000010"
CASE 6
senddata$ =
"011101010001110000000010"
CASE 7
senddata$ =
"011101010001110000000010"
CASE 8
senddata$ =
"011101010001110000000010"
CASE 9
senddata$ =
"N011101010001110000000010"
END SELECT
' pulsecount = len(senddata$)*2
SEND433MHZ(pulselength,repeat,xmitpin,senddata$)
ENDIF
END SUB

SUB SEND433MHZ(pulselength AS FLOAT,repeat AS INTEGER ,thexmitpin AS INTEGER,senddata$ AS STRING)
LOCAL INTEGER long,short
LOCAL INTEGER j,i,n

short=pulselength
long=pulselength*
3
IF LEFT$(senddata$,1) = "N" THEN
n =
1
senddata$ =
MID$(senddata$,2)
'print "Noise"
ENDIF

lengths(
0)=short
lengths(
1)=short*31 'sync pulse
FOR i=1 TO LEN(senddata$)
IF MID$(senddata$,i,1) = "1" THEN
'One
lengths(i*2)=long
lengths(i*
2+1)=short
ELSE
'Zero
lengths(i*2)=short
lengths(i*
2+1)=long
END IF

NEXT i

' Call the CFunction
IF n = 1 THEN bitbanger(thexmitpin,254,noise())
FOR j=0 TO repeat-1
bitbanger(thexmitpin,
LEN(senddata$)*2+2,lengths())
NEXT j
END SUB

CSUB bitbanger INTEGER,INTEGER,FLOAT 'pin number, number of bits, floating point array of bit lengths in usec
00000000
27BDFFC0 AFBF003C AFBE0038 AFB70034 AFB60030 AFB5002C AFB30024 AFB20020
AFB1001C AFB00018 AFB40028
3C109D00 8E030000 00808821 8E020080 8C640000
00A09021 00002821 00C0B021 0040F809 8E140064 00409821 8E02009C 3C0449F4
0040F809 24842400 00402821 0280F809 02602021 0040B821 8E240000 8E020024
24050007 0040F809 241E0001 AFA20010 8E020028 0040F809 8E240000 8E520000
8E030040 005EF004 0060F809 00122080 AFA20014 12400013 0040A821 0000A021
00008821 3C139D00 0014A080 02D41821 8C640000 8E620058 8E70007C 0040F809
02E02821 26310001 0200F809 00402021 02B4A021 0232182B AE820000 1460FFF2
0220A021 8FA30014 3C040008 8C620000 2442FFFD AC620000 3C03BF88 AC641064
3C03BF88 00001021 AC601068 40824800 8FA50014 8FA30010 2652FFFF AC7E0000
8CA40000 00442021 40024800 0044182B 1460FFFD 00000000 1640FFF6 24A50004
8FBF003C 3C020008 3C03BF88 AC621064 3C03BF88 8FBE0038 8FB70034 8FB60030
8FB5002C 8FB40028 8FB30024 8FB20020 8FB1001C 8FB00018 AC621068 03E00008
27BD0040
END CSUB


enter 0 to 9 to select the code you want to send. All codes are the same in this demo except No 9 which has an "N" as the first digit.
This cause a burst of random noise to be sent before the data.

The pulse length is set at 295uS which might need tweaking. Long pulses are 3 times the short ones.

Thanks to PeterM and disco4now for the code I based it on.

If it looks OK, I will start playing with receiving the data.

Jim
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 11:22pm 16 Mar 2018
Copy link to clipboard 
Print this post

Hi Jim.

Thanks very much for your efforts!

Do you want me to capture the output of your code from the 170, into the logic analyser and compare with the actual transmitter?

I think that is what you want me to do, yes?

EDIT: I can't feed it into the TX and then receive on the receiver, as the Tx units are sealed watches, and unless you want me to hack one of those to bypass the 1527, and inject the data to the TX side of the device and then receive THAT across the link....

I can put up a photo of the internals of the watch TX if you like, but it is just a small PCB with the TX AND encoder all on one, along with the button and batteries.Edited by Grogster 2018-03-18
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 11:51pm 16 Mar 2018
Copy link to clipboard 
Print this post

Just feed the output directly into your logic analyser and compare.

I am looking for a way of testing various receive decoding methods without having the transmitter or receiver.

Jim
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 06:31am 17 Mar 2018
Copy link to clipboard 
Print this post

Hi there.

@ TassyJim - Here is the data you requested. I have run tests 1 and 9. If you need more tests, please let me know.

2018-03-17_163102_TassyJim_01tests_1_and_9.zip
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 06:51am 17 Mar 2018
Copy link to clipboard 
Print this post

That looks good enough to play with.

Jim
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 06:53am 17 Mar 2018
Copy link to clipboard 
Print this post

Awesome.

Do you want me to do any of the other tests? (2-8)
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 11:40pm 17 Mar 2018
Copy link to clipboard 
Print this post

When I 'sent' this
"011101010001110000000010"

I received and decoded this
"001110101000111000000001000111010100011100000000100011101010001110000000010"

Which is the sent code repeated 3 times. The extra zeros are the sync pulses.

The sender is a 170 and the receiver is an explore64.

The receiving code is basically the one I posted earlier in the discussion.

I need to sort out the sync pulse timing and try some other, faster methods of decoding to get it running on an 170 although I assume you have a few spare explore64s available.

By using the simulator instead of the real thing, I can push the speeds up to see how close we are to failure.

Jim
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 12:42am 18 Mar 2018
Copy link to clipboard 
Print this post

Marvellous, thanks for your efforts.

Yes, I have E64's here if I need to use one for testing anything you need.
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 05:28am 18 Mar 2018
Copy link to clipboard 
Print this post

  Quote   ' exp64 decoder
DIM INTEGER tick, tock, period, pulsetime = 50, synctime = pulsetime * 10
DIM code$
DIM pulses(500) ' store all timing intervals for later processing
DIM inSync ' used to signal when sync pulse has been received
DIM pulsecount
DIM firstRun, syncs
DIM validAlarms$(20)
CONST ticker = 49 ' connect PWM output (pin 48) to here
CONST rxPin = 46 ' pin that the receiver output connects to
validAlarms$(1) = "011101010001110000000010"
validAlarms$(
2) = "011101010001110000100010"
validAlarms$(
3) = "011101010001110001100010"
validAlarms$(
4) = "011101010001110000000001"
validAlarms$(
5) = "011101010101110000000010"
validAlarms$(
6) = "011101011101110110100010"
validAlarms$(
7) = "011101011001110001100010"
validAlarms$(
8) = "011101011001110000000010"
validAlarms$(
9) = "011101011111110000000010"
validAlarms$(
10) = "011101000001110000100010"
validAlarms$(
11) = "011101100001110001100010"
validAlarms$(
12) = "011101010001110001000001"
validAlarms$(
13) = "010101010001110000000010"
validAlarms$(
14) = "011001010001110000100010"
validAlarms$(
15) = "011011010001110001100010"
validAlarms$(
16) = "011101010001110100000001"
validAlarms$(
17) = "011101010001111100000010"
validAlarms$(
18) = "011101010001101000100010"
validAlarms$(
19) = "011101010001000001100010"
validAlarms$(
20) = "011101010000110000000001"

PWM 1, 100000, 50 ' this is out high resolution timer whch gets connected to ticker pin
SETPIN ticker, CIN
SETPIN rxPin, INTB, blip ' triggers on a high or low transition
tock = PIN(ticker)
SETTICK 3000, checkit

DO
' IF INKEY$<>"" THEN
' decode
' ENDIF
LOOP

END

SUB blip
tick =
PIN(ticker)
IF inSync = 0 THEN
IF (tick - tock) > synctime AND PIN(rxPin) = 1 THEN' long enough to have been sync pulse
inSync = 1
pulsecount =
0
pulses(pulsecount) = tick - tock
ENDIF
ELSE
pulsecount = pulsecount +
1
pulses(pulsecount) = tick - tock
IF pulsecount > 400 THEN
inSync =
0
pulsecount =
0
'print "overflow"
ENDIF
ENDIF
tock = tick
END SUB

SUB checkit
LOCAL n, t
t =
TIMER
decode
FOR n = 1 TO 20
IF validAlarms$(n)<>"" THEN
IF INSTR(code$,"s"+validAlarms$(n))>0 THEN ' we have lift off!!
PRINT "!!!! ",n, " needs help!"
ENDIF
ENDIF
NEXT n
PRINT "Checkit time ",TIMER - t
END SUB

SUB decode
LOCAL n, pulsetimes
code$ =
""
' check every second timing
PRINT pulses(0) 'DEBUG
pulsetimes = 0 'DEBUG
FOR n = 1 TO 400 STEP 2
pulsetimes = pulsetimes + pulses(n)+pulses(n+
1) 'DEBUG
PRINT pulses(n), pulses(n+1), pulsetimes 'DEBUG
IF pulses(n) > synctime OR pulses(n+1) > synctime THEN ' a sync pulse
code$ = code$ + "s"
ELSEIF (pulses(n) + pulses(n+1)) = 0 THEN ' all done
EXIT FOR
ELSEIF pulses(n+1) = 0 AND pulses(n) < pulsetime THEN ' final transition
code$ = code$ + "0"
ELSEIF pulses(n) > pulses(n+1) THEN
code$ = code$ +
"1"
ELSE
code$ = code$ +
"0"
ENDIF
NEXT n
PRINT code$ 'DEBUG
inSync = 0
syncs =
0
pulsecount =
0
FOR n = 1 TO 400
pulses(n) =
0
NEXT n
END SUB

How it works.

The PWM 1 output is connected to a counting pin with a frequency of 100kHz. That gives us a tick counter of 10uS
On the explorer64, PWM is on pin 48 which is conveniently next to count pin 49

I used pin 46 for the radio receiver input but any would do.

The interrupt routine attempts to wait for a sync pulse then fills the pulses()array with the time intervals. It is limited to 400 ticks so we don't overflow our string when it comes to decoding. After 400 ticks, it loops from the start.

There is a SETTICK timer which periodically checks the pulses() array and looks for patterns it recognises.
It is set to 3 seconds for testing but should be as often as possible once the debug printing is removed.
I would try 500mS to start with.

There is a timer to keep track of time taken to decode to enable setting the best decode interval.

The decode SUB scans the array and looks for sync pulses.
It also compares two adjacent time intervals and decides if we have a "1" or "0"
The results are stored in a string.

The string is then scanned for each of the "residents codes" and if found, raises an alarm.


If the receiver doesn't have a squelch, the code will spend a lot of time in the interrupt SUB.


The main thing to check is the different times saved for 'short' and 'long' pulses
  Quote  
89 44 23301
72 44 23417
75 44 23536
44 58 23638
44 73 23755
43 75 23873
90 43 24006
73 44 24123
44 60 24227
45 71 24343
45 72 24460
89 44 24593
44 0 24637
0 0 24637
s011101010001110000100010s011101010001110000100010s01110101000111000010001ss011101010001110001100010s0111010100011100011 00010s011101010001110001100010
!!!! 2 needs help!
!!!! 3 needs help!


If the times are too close together, we have reached to limits of the micromite.
In the above example I sent two codes quickly and both were found in the one string.

You need to fill the array with some valid codes.
2018-03-18_152629_panicalarm.zip
I have attached this file for the exp64 and an updated sending file for the MX170 with the device codes set to match sender and receiver. code 9 still send code 1 with noise at the start.

Clear as mud?

Jim

VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 07:01am 18 Mar 2018
Copy link to clipboard 
Print this post

AWESOME!

Thank you VERY much for your efforts. I will load this into an E64 tomorrow. I wish I could tonight, but I don't have time.

With the array storing the remote addresses, that will work beautifully. If I wanted to LEARN a new remote code into the system, is there much involved in that kind of idea? I know this is not part of your demo code, and I may well be able to work it out from the sample code you have supplied......
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 07:29am 18 Mar 2018
Copy link to clipboard 
Print this post

To learn a new code, run it with PRINT code$ active. That will give you a line similar to the example output. Copy the data between two 's' markers and paste it into the array section of the program. If you have a good decode, there will be three the same in the string. In practice, checking the string every 500mS or more often is required to prevent overwriting good data with noise. This means you are likely to get half a code in most strings but with three being sent, there should always be at least one good one.

It could be automated without too much effort but lets see how well it works in real life first.

Jim
VK7JH
MMedit
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1127
Posted: 08:17pm 19 Mar 2018
Copy link to clipboard 
Print this post

To add to the confusion, looking at Grogster's screen shot, and later link to the wider screen image, the valid data starts just before about the 30ms mark. The long low pulse is the inter-packet delay.

My original decoding firmware always missed the first packet because the noise was being interpreted as valid pulses that weren't cleaned up until a long low appeared.

Before changing to a better receiver, my software plan was to pay more attention to pulse lengths. Pulses representing zero and one bits have fairly specific lengths, although this jitters a bit because there is no synchronization between transmitter and receiving software. My plan was to reset the incoming pulse count any time the pulse was shorter than the shortest valid pulse or longer than the longest one. How much shorter or longer? Well, I never got around to actually trying different values because of the change in hardware.

This firmware was to be running in C or assembly on the target microcontroller. I have no idea if interpreted MMBasic is fast enough to catch these subtle variations in pulse length.

Using hardware with a radio signal strength indicator really simplified things.
Visit Vegipete's *Mite Library for cool programs.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 11:22pm 21 Mar 2018
Copy link to clipboard 
Print this post

Finally had a chance to play with this. Sorry for the delay. It appears to be working with my test transmitter unit: (E64 1C, MMBASIC 5.04.08, default speed(100MHz))







First image is just me running the code, 2nd image is with me putting the transmitter code into slot #20, which then does respond.

So, this is the first actual test with the actual transmitter and not just with a simulator, but they seem to agree.

Anything else you would like me to try?

Smoke makes things work. When the smoke gets out, it stops!
 
Azure

Guru

Joined: 09/11/2017
Location: Australia
Posts: 446
Posted: 11:42pm 21 Mar 2018
Copy link to clipboard 
Print this post

If it's not too long can you post the current code being used.

My only suggestion is it needs a valid sync detected before it attempts to decode. That way it wont try to decode the noise.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 11:47pm 21 Mar 2018
Copy link to clipboard 
Print this post

Go back to the end of page 6.

It's a direct copy of the code Jim posted for me to try.
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 01:51am 22 Mar 2018
Copy link to clipboard 
Print this post

That is very promising.
It shows that my timing was close to the real thing.

The next big thing is to get access to the WAKEB pin on the IC and use it as an interrupt to configure the main data interrupt. I would set the data interrupt ON when you have RF and OFF when it stops. That should prevent any overwriting.

Jim
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9586
Posted: 03:16am 22 Mar 2018
Copy link to clipboard 
Print this post

Cool, I will try that next. I should configure the interrupt pin(from WAKEB) to fire the BLIP sub, yes?
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 04:38am 22 Mar 2018
Copy link to clipboard 
Print this post

THis is how I would try:
  Quote   SETPIN wakeb, INTB, arm ' sets the mite ready to decode

SUB arm
IF PIN(wakeb) = 0 THEN ' we have data arriving
SETPIN rxPin, INTB, blip
ELSE
SETPIN rxPin, OFF ' data has finished
ENDIF
END SUB


rem out the original "SETPIN rxPin, INTB, blip"

The interrupt to blip is only active when there is likely data arriving.
It is not called at all when there is no RF.

Jim

VK7JH
MMedit
 
     Page 4 of 5    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025