【单片机相关】Remote control based on c8051 with 433MHz radio modules

本文介绍了使用Silabs C8051F321微控制器结合433MHz无线电模块实现RF远程控制的技术细节,包括UART通信协议的解决、代码实现以及模块化设计,旨在提升按钮数量并实现在不同距离下的有效控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.codeproject.com/Articles/55864/Remote-control-based-on-c8051-with-433MHz-radio-mo

原文链接


Download receiver source - 5.96 KB
Download transmitter source - 5.9 KB
Download VB6 source - 13.2 KB
Download remote hex file - 2.45 KB
Download transmitter hex file - 2.28 KB


Introduction

This article is about the very well known RF modules TX433 and RX433 that (or similar) can be found almost in every electronics shop, and a pair of them costs ~15 bucks.



Using the Silabs C8051F321 microcontroller.



I searched the internet for a 'radio remote control' with more than 8 buttons, but found none. So I decided to program one myself. At first, it seemed an easy task as I have programmed microcontrollers before.

See my other articles on Silabs c8051:
USB IR with c8051
Counter based c8051
LCD with USB Toolstick c8051

Luckily, I got the idea for this task from reading some other examples:
Running TX433 and RX433 RF modules with AVR microcontrollers

The problem was to find a solution to the UART communication protocol for radio communication. You need to know a way to read and write to UART in C, that is different than Keil and MCU-s like Silabs ones. The problem is finding a solution not to echo back when reading UART signals. To read UART signals, you must use low-level functions (_getkey) and use interrupts to signal timers that control IO-s.
Collapse | Copy Code
// SFR Paged version of _getkey
char _getkey () {
char c;
while (!RI0); //wait UART receive interrupt to trigger
c = SBUF0; //read char from UART
RI0 = 0; //signal recieve ready
return (c);
}

At first, I got nothing but garbage from the hypertrminal. Then, I decided to use the other USB-to-Serial cable, and it worked. It has reversed polarity (UART signals are inverted compared to the RS232 signals). One solution to this is to use MAX232 or a transistor to the reverse polarity - I chose the last method.

This is the result:



Large pictures are available here: RX1, RX2, TX.

My mission is to use more than 8 buttons, which is the usual count of buttons in modules like thes, for example: Wellmann catalogue (VM118). The buttons count is limited due to the manufactured controllers-encryption/decryption modules chips limitations. This restriction can be overridden by writing receive-transmission codes yourself. To achieve this goal, I used the well-known Silabs MCU-s C8051F321, but with small modifications, it can used with many other Silabs chips as well.

The transmitting-receiving distance can have a range up to ~50m when applying 15cm antennas. In my case, I used a UART 2400 baud rate. The maximum is 4800bps. But as explained in many places in the internet, and from testing the modules, the recommended connection speed would be 2400bps for better noise/distance ratio.

Many modules are sold and used at the maximum baud rate for a small distance ~10 meters or so, and that's even with antennas. I find that insufficient.

So first, I looked at an example code here: Running TX433 and RX433 RF modules with AVR microcontrollers. It explains the radio packets structure basics (protocol) for these modules:
Sending packet sync - it may be any character
Sending address
Sending a control (verification) byte

---------------
Sending a carriage return character '13' or '\r'
Waiting for a few ms ~ 10ms
If a button is pressed: the same procedure is repeated again

Receiver waits for synchronization characters (I made that 'SW' for abbreviation, e.g., switch) because the receiver reads a lot of noise while waiting (and we do not want false triggering). After that:
Reads address bits (two bits, e.g., '00' or '21')
Reads a control byte character
Compares the control byte to the address, and if they match, triggers address port to high level
Waits ~100ms and switches all ports to low again (port pulse switching)
If another signal is read before timeout occurs, switches that new port high and old off

Basically, all relays are switched off while no button is pressed.

The purpose of this module is to control the crane movements of the vehicle that moves the garbage containers. (You can't find any of the modified code in modules bought from a shop). In those, you don't need to worry about interferences with other remotes in range.
Background

To read UART pulses with serial port (COM port), you must invert the polarity of signals with transistors or using MAX232. Without reversing the polarity, it is possible to gain connection and also get the device to work, but it will lack the possibility to read signals with the hyperterminal. That means no debug facility. To debug the program, I used a USB-to-Serial adapter like the USB - UART interface in 'Counter based c8051' and read signals with the Silabs debug adapter, for which the firmware was updated. Also, to read, I use my USB terminal 'usbhidio3.exe'.



Hardware schematics:





To update firmware and debug, use Silabs 'Toolstick Base Adapter':






Using the code

The code for the microcontroller is written within Silabs IDE 3.61.00 and compiled with the Keil compiler ver. 8.17. If any button is pressed, a signal like 'SW01b\r' is written to the UART of c8051F321 and the TX433 module sends a code to the receiver RX433. Accordingly, the receiver decodes and lights the LED of that channel (or pulses a relay - if it's connected to the matching port output of the microcontroller).

Here is the basic Tx main module:
Collapse | Copy Code
void main (void)
{

PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
Timer0_Init (); // Initialize the Timer0 enable)

PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
UART0_Init();

EA = 1; // Enable global interrupts
//LED =0;
while (1)
{
if(LED==0)
{
if(SW00==0){
bSwitch=1;
printf ("SW00a%c",13);
}
if(SW01==0){
bSwitch=1;
printf ("SW01b%c",13);
}
if(SW02==0){
bSwitch=1;
printf ("SW02c%c",13);
}
if(SW03==0) {
bSwitch=1;
printf ("SW03d%c",13);
}
if(SW06==0){
bSwitch=1;
printf ("SW06g%c",13);
}
if(SW07==0) {
bSwitch=1;
printf ("SW07h%c",13);
}
if(SW10==0) {
bSwitch=1;
printf ("SW10k%c",13);
}
if(SW11==0) {
bSwitch=1;
printf ("SW11l%c",13);
}
if(SW12==0) {
bSwitch=1;
printf ("SW12m%c",13);
}
if(SW13==0) {
bSwitch=1;
printf ("SW13n%c",13);
}
if(SW14==0) {
bSwitch=1;
printf ("SW14o%c",13);
}
if(SW15==0) {
bSwitch=1;
printf ("SW15p%c",13);
}
if(SW16==0) {
bSwitch=1;
printf ("SW16q%c",13);
}
if(SW17==0) {
bSwitch=1;
printf ("SW17r%c",13);
}
if(SW20==0) {
bSwitch=1;
printf ("SW20u%c",13);
}
if(SW21==0) {
bSwitch=1;
printf ("SW21v%c",13);
}
//if(SW22==0) printf (" SW22w\n");
if(SW23 == 0) {
bSwitch=1;
printf ("SW23x%c",13);
}
//printf ("\nSW%ca",cOut);
if(bSwitch == 1){
bSwitch= 0;
LED = 1;
}
}//end of IF LED=0;
}//end while
}

The receiver tst_gets module behaves like this:
Collapse | Copy Code
void tst_gets (void) {

//char c; // temporary char

int i = 2; // temporary int
unsigned long temp_amplitude;
unsigned char chksum;

LED = 0;
while( _getkey() != 'S' ); // ignore all characters until
if(_getkey() == 'W')
{
LED = 1;
temp_amplitude = hex2char();
chksum = _getkey();
//printf("NR:%ld: %c - %bd\r", temp_amplitude, chksum,chksum-97);
if(temp_amplitude == chksum-97)
{
//printf ("EQ\r");
if(temp_amplitude==0){
P0=1;
P1=0;
P2=0;
}else{
if (temp_amplitude < 10) {
//temp_amplitude = temp_amplitude;
P0 = SINE_TABLE[temp_amplitude];
P1=0;
P2=0;
} else if (temp_amplitude < 20) {
temp_amplitude -= 10;
P1 = SINE_TABLE[temp_amplitude];
P0=0;
P2=0;
} else if (temp_amplitude < 30) {
temp_amplitude -= 20;
P2 = SINE_TABLE[temp_amplitude];
P0=0;
P1=0;
}//temp_amplitude < 10
}//if(temp_amplitude==0
counter = 0;
}//if(temp_amplitude == chksum-97)
}
}
Software links:
Silabs IDE: http://www.silabs.com/products/mcu/Pages/SiliconLaboratoriesIDE.aspx
http://www.silabs.com/Support%20Documents/Software/mcu_ide.zip
Keil Compiler: http://www.keil.com/demo/download.asp. C51 evaluation software. You can compile with the evaluation software, because the code size is less than 4K.
License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值