News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Comparing characters in an array

Started by david, Oct 09, 2022, 10:53 AM

Previous topic - Next topic

david

Hi All,
I've resurrected a very old project using a 12F675 and ASK RF modules and was looking to adapt it for points control for an old friend's garden railway.   I thought if I could send a channel number (repeated 4x) and a state value (repeated 3x) it would give better noise immunity.

This is what I have-
Dim chan[4] As Byte     'channel number  1111, 2222, 3333...
Dim state[3] As Byte    'state -ON/OFF   000=ON  111=OFF

SerIn RxIn,17197,[Wait("sync"),Str chan, Str state] '17197=1200 inverted
If chan[0]="1" And chan[1]="1" And chan[2]="1" And chan[3]="1" Then GoTo.....

Is there a more elegant way of checking the received chan[4] string?

Is it better to convert to a decimal number for comparison?
ID=Val(chan,Dec)
If ID=1111 Then GoTo......

If someone has already done a simple RF link with "channels" and "state" I would be keen to hear suggestions.

Cheers,
David


 

top204

#1
With the 8-bit devices, it is better to write it as:

If chan#0 ="1" And chan#1 = "1" And chan#2 = "1" And chan#3 = "1" Then GoTo xxx

This is because of the fragmented RAM inside them, so the compiler does not need to call its library subroutine to find the array's address in the fragmented RAM, everytime an element of it is required.

Also, it is better to use:

If chan#0 ="1" Then
    If chan#1 = "1" Then
        If chan#2 = "1" Then
            If chan#3 = "1" Then
                GoTo xxx
            EndIf
        EndIf
    EndIf
EndIf

So that the compiler does not need to use any RAM for its boolean comparison stack. The above works nicely with "Ands only" in a comparison, as long as the code does not need an Else with them.

A lot of people, using all languages, mistake a single line of high level code being the most efficient, whereas a compiler's code generator can be more efficient when multiple lines are used, so it does not need to second-guess and use worse case scenario code.

The compiler's functions to convert a Byte array will need a null terminator attached to the end of the array's contents, so it imitates a String type variable. Otherwise, they will not know where the ASCII text finishes.

John Drew

#2
Hi David,
In one of my projects I just encode everything into 1 byte.
The presence or otherwise of a bit gives on and off. 8 channels.
Byte 01100011 would indicate channels 0,1,5 and 6 are on the rest off.
Perhaps send it several times and check for match if you wish.
Then recreate the channels at the other end from the bits.
Yes, it might take more code but it's much sweeter in my view.
Cheers
John

PS expand the concept to 16 points using a word etc

david

Quote from: top204 on Oct 09, 2022, 11:07 AMWith the 8-bit devices, it is better to write it as:

If chan#0 ="1" And chan#1 = "1" And chan#2 = "1" And chan#3 = "1" Then GoTo xxx

This is because of the fragmented RAM inside them, so the compiler does not need to call its library subroutine to find the array's address in the fragmented RAM, everytime an element of it is required.

Also, it is better to use:

If chan#0 ="1" Then
    If chan#1 = "1" Then
        If chan#2 = "1" Then
            If chan#3 = "1" Then
                GoTo xxx
            EndIf
        EndIf
    EndIf
EndIf

So that the compiler does not need to use any RAM for its boolean comparison stack. The above works nicely with "Ands only" in a comparison, as long as the code does not need an Else with them.

A lot of people, using all languages, mistake a single line of high level code being the most efficient, whereas a compiler's code generator can be more efficient when multiple lines are used, so it does not need to second-guess and use worse case scenario code.

The compiler's functions to convert a Byte array will need a null terminator attached to the end of the array's contents, so it imitates a String type variable. Otherwise, they will not know where the ASCII text finishes.

Many thanks for the clarification Les.   I was aware of the string limitations of vintage, jelly bean PICs but had never had to use them in this way before.  Yes I'm guilty of needlessly fitting the compare code on one line. I tend to think of it as a simple comparison rather than how the micro thinks of it.

Best regards,
David


david

Quote from: John Drew on Oct 09, 2022, 12:24 PMHi David,
In one of my projects I just encode everything into 1 byte.
The presence or otherwise of a bit gives on and off. 8 channels.
Byte 01100011 would indicate channels 0,1,5 and 6 are on the rest off.
Perhaps send it several times and check for match if you wish.
Then recreate the channels at the other end from the bits.
Yes, it might take more code but it's much sweeter in my view.
Cheers
John

PS expand the concept to 16 points using a word etc

Hello John,
I like the approach but with ASK RF modules there's always the uncertainty as to what signals can sneak through when the tx is off so the need to repeat the data would be advised.  Your method has the advantage of being able to update all channels at once whereas I was going to have the tx only transmit when a single channel changed state.
I think repeating the data a few times should make it fairly robust to noise and each receiver is only looking for its own channel bit anyway.    I think it's a much better idea - there goes another day changing code.....

Cheers,
David

John Drew

Hi David,
You're right about radio links.
My links have always had more than one byte and I create a simple checksum. Sometimes just the sum of the numbers allowed to overflow in a byte.
Works OK. Maybe I'd do something better for the Indian Pacific Railway :)
If using a modulated carrier I'd always prefer FM than AM.

Cheers from across The Ditch
John

david

Quote from: John Drew on Oct 10, 2022, 02:57 AMHi David,
You're right about radio links.
My links have always had more than one byte and I create a simple checksum. Sometimes just the sum of the numbers allowed to overflow in a byte.
Works OK. Maybe I'd do something better for the Indian Pacific Railway :)
If using a modulated carrier I'd always prefer FM than AM.

Cheers from across The Ditch
John

Hello John,
Yes FM is to be preferred if it's permitted - it has the advantage of suppressing noise (for a zero bit)and the FM capture ratio allows nearly similar level signals to be almost totally rejected.  Full carrier for both a one and a zero is a big help.
Thinking about your rather digital protocol - it will need other items to ensure the data is valid.  It occurred to me that the situation with all channels OFF is the same as loss of carrier (or out of range) for an ASK module so a robust sync and checksum may be required.  I don't have the modules yet so range is an unknown and it may turn out I can use something simple.  It's an interesting subject that's been around a long time - data confidence in noisy simplex links.
I do have a pair of cheap FM modules on 868MHz - I ran out of park when range testing them with serial data - 200m+

Cheers,
David

JonW

I would definitely add preamble to the start of transmission on any ASK comms to get the data slicer charged correctly.  Take a look at the HC-12 modules using the Silabs transceivers, I am using these for a rugby club digital sign and they operate flawlessly over a long range and include all encoding onboard so simple serial is all that's required.  I have added Power switch to fully isolate the module and sleep the processor to enable long term use from batteries.  The HC-12 buffer is limited to 16 bytes for a single transmission.
I have built a full waterproof push button remote and a PC interface to update the text and memory remotely and have multiple channels.  I use a preamble nibble and the number transmitted bytes as the first byte, channel byte, data, data data checksum and terminator byte.  The terminator byte can be used to trigger the end of the serial receive or wait for a pause in transmission (serial) use the byte transmission nibble to calculate the number of bytes in the packet (if you have variable data)

For channel decoding I use select case on the channel byte.





John Drew

I'm ignorant about "ASK comms".
Any help?
I guess it's a digital system.

FM modulation with an unbroken carrier is very reliable as David mentioned. On the other hand a switched carrier is wide open to problems.

I'll read up on the modules and learn something.
John

John Drew

OK, research done. It uses FSK which is commonly used in amateur digital radio applications. Hardly interference tolerant so you'll need checksums.
Remarkable sensitivity of better than -124dBm in the receiver but relying on digital filters for selectivity.

Should still send a zero so channels etc encoded into single byte but repeated byte plus checksum should work OK.

Very few of the 100 channels of the HC-12 can legally be used in Australia.
LIPD band 433.05-434.79MHz so first 5 channels. 25mW output or 14 dBm max.

Be aware, a worldwide Amateur band covers 430-450MHz with some hams running legal limit of at least 400W PEP mostly around 432.1MHz. That will give the front end of the receiver a hurry up.

There is a fair bit of amateur activity in the licensed 430-450 band e.g Beacons, Repeaters, SSB operation. Downlinks and some Uplinks of amateur satellites mostly around 437-438. I use a number of these satellites and often chat through the repeater on the space station. And occasionally chat with an Astronaut.

AR is a fascinating hobby. We're currently waiting for the moon rocket to finally launch. It has a Japanese moon satellite and lander
on board so we're preparing to listen for that on the same amateur band.

Sorry about the digression.
John


JonW

John

The 4463 will operate from 142 - 1050MHz and its the onboard MCU and tuning that limits the frequency range, i guess you could reprogram the STM32 if you wanted to reuse the PCB, the IC will work broadband and is a pretty good low cost synth in its own right!.  The modules are optimised for 433MHz but if you do have some local interference you can always add the provision for an external saw filter on the front end, as these are TDD transceivers you will only need 1 filter, however most modules on the market have the LNA's wide open.  Many moons ago we developed a OOK transceiver with some old Plessy receiver IC's and added SAW filters and external BJT LNA and some funky printed narrowband antennas and with low data rates we could get to -120dBm sensitivity!

 

david

Much as I would love to use Silabs chips this is real bottom end RF modules I'm looking to use.
The receiver is at least a full superhet complete with AGC so that should go some way to controlling noise when the carrier is momentarily off during byte transmission.  I'll certainly use a preamble before syncing to set the AGC level.  Sensitivity is given as -107dBm.  Just hope one of John's mates isn't in the area as I think the front end selectivity will be very modest.

Cheers,
David
RF modules.PNG

John Drew

Wow Jon,
You're way ahead of me with technology. You've been involved in some really interesting projects.
There's some very talented people on this forum.
Cheers
John

JonW

Jeez that's crazy cheap.  You should look at using Manchester encoding the data on OOK modules to improve the accuracy of the data slicer and improve synchronization.  It does halve your data throughput but does improve the quality of the link.  Also keep the data rate as low as possible to improve the SNR

J

david

Yes that's NZ$ too - worth about US$0.56.
Roman Black did a write-up on cheap RF modules. 
 https://www.romanblack.com/RF/cheapRFmodules.htm
He talks about the "myth of Manchester encoding" but also comes up with a much wider bandwidth data system.  It's a good read.

Cheers,
David

JonW

The RX modules he is using looks like superregen architecture, they are very susceptible to duty cycle variations vs data rates.  The newer are full superhet's with AGC so may be fine in your application. Give it a whirl.  Tip make sure you have a decent ground plane to ensure your antenna is optimum, a tiny spiral antenna is good for small ground planes and about as cheap as you can get. 




david

I wouldn't like to comment on the topology of the modules he used.  Superregen rxs can be very sensitive but are fairly broadband and often extremely loud radiators making it difficult to have several rxs in the same location.  I'm looking forward to trying these cheapy rxs and will start with a normal mode helical antenna because it's easy and compact.  Ground plane will be almost non-existent - only a tiny circuit board and a small Lipo battery. Not a serious project but it keeps me off the streets....

David

Dolci

Anyone has a sample code for 433mhz RF modules for a startup. I got this rf modules lying years in my junks ;D

can't upload the image :'(

top204

#18
Crickey... I remember using the very low cost, and then quite new, 433MHz transmitter and receiver boards back in the year 2000 when I was writing my book. :-) Wow... What has happened to the years? They have just flown by so quickly. :-(

If the boards are just carrier on/off types, the easiest way to test them and use them is to use standard async coms and set the Baud very low so the RX module's data slicer can work. Then send a pre-amble byte of either $AA or $55 before sending the data. With the even bits of the values, it allows the RX module's slicer to sort itself out for the actual data. Depending on the RF module specifications, Baud rates from 300 to 1200 should work nicely.

When using standard async coms, the RSout/RSin or HSerin/HSerout commands can be used without any problems.

Dolci

thank you top204 for the advice.. any chance you still have that piece of code?