Arduino radio hc-12: Difference between revisions
| (2 intermediate revisions by the same user not shown) | |||
| Line 304: | Line 304: | ||
DIY Yagi | DIY Yagi | ||
* https://www.instructables.com/DIY-Yagi-Antenna-for-LoRa/ | * https://www.instructables.com/DIY-Yagi-Antenna-for-LoRa/ and https://www.youtube.com/watch?v=gA5SCXw_E1Q | ||
* https://www.slideshare.net/slideshow/yagi-antenna-design-and-433mhz-antenna-design-examplepdf/253836272 | |||
* Not a yagi https://www.instructables.com/433-MHz-Coil-loaded-antenna/ | |||
== References == | == References == | ||
Latest revision as of 17:05, 17 December 2025
Introduction
Idea: The protocols are usually based on transmitting characters. Thus, easiest method is to transfer csv as strings and then cast the type to floats in the receiving program. If using cansat, also the time stamp is extremely important. We try to use Linux as a receiving machine.
UART (Universal Asynchronous Receiver-Transmitter) communication. Serial communication is expecting (a pointer to) a string.
LoRa, hc12, hc-12
- Frequency band is from 433.4 MHz to 473.0 MHz
- 100 channels with a stepping of 400 KHz between each channel
- Transmitting power is from -1dBm (0.79mW) to 20dBm (100mW). A half-duplex 20 dBm (100 mW) transmitter
- Receiving sensitivity is from -117dBm (0.019pW) to -100dBm (10pW)
- Supply Voltage: 3.2V to 5.5V
Connect a 22 µF to 1 mF reservoir capacitor in parallel with the HC-12 "Gnd" and "Vcc" pins.
Datasheet: https://statics3.seeedstudio.com/assets/file/bazaar/product/HC-12_english_datasheets.pdf
Terminal program
Terminal br@dy https://sites.google.com/site/terminalbpp/
PuTTY (on Windows):
- Session -> Serial, and find the correct COM (can be found at Device Manager).
- Terminal -> 'Implicit CR in every LF' box. (https://forum.arduino.cc/t/putty-settings-to-emulate-the-arduino-serial-monitor/577906)
- Local echo: 'Force on' to echo to your screen
- Local line editing: 'Force on' to send only after pressing enter
Set
Pins:
- Set pin of the module to Ground (set the pin to low logic level).
- Vcc 3.3V and GND to GND
- TXD -> 11
- RXD -> 10
Note that the pins needs to be reversed: The TX pin in the HC-12 needs to be plugged to RX pin of the Arduino.
The syntax of the softaware serial is:
SoftwareSerial(rxPin, txPin, inverse_logic)
Code for setting AT commands:
#include <SoftwareSerial.h>
SoftwareSerial HC12(11, 10); // HC-12 TX Pin, HC-12 RX Pin
void setup() {
Serial.begin(9600);
HC12.begin(9600);
}
void loop() {
while (HC12.available()) { // If HC-12 has data
Serial.write(HC12.read()); // Send the data to Serial monitor
}
while (Serial.available()) { // If Serial monitor has data
HC12.write(Serial.read()); // Send that data to HC-12
}
}
AT commands. The most important commands are (remember to use capital letters)
- AT – test command. It will return OK if AT interface is enabled
- AT+Bxxxx – set serial port baud rate. For example, AT+B57600 set baud rate to 57600bps, AT+B9600. Available baud rates: 1200 bps, 2400 bps, 4800 bps, 9600 bps, 19200 bps, 38400 bps, 57600 bps, and 115200 bps. Default: 9600 bps.
- AT+Cxxx – set radio channel. Channels start from 001 at 433,4MHz. Each next channel adds 400kHz. Channel 100 is 473,0MHz. AT+C002 will set frequency to 433,8MHz. Two HC-12 devices that creates a wireless link have to operate on the same frequency
- AT+FUx – set device mode: FU1, FU2, FU3 or FU4. Two HC-12 devices that creates a wireless link have to use the same mode
- AT+Px – set device transmitting power. For example AT+P2 sets power to 2dBm (1.6mW)
- -1dBm (0.8mW)
- 2dBm (1.6mW)
- 5dBm (3.2mw)
- 8dBm (6.3mW)
- 11dBm (12mW)
- 14dBm (25mW)
- 17dBm (50mW)
- 20dBm (100mW)
- AT+RX – retrieve all parameters: mode, channel, baud rate, power
- AT+V – retrieve module version
- AT+DEFAULT – reset module parameters to default settings
Software Serial Commands
HC-12
- print (turns number into a string and sends it)
- write (Serial.write() sends one byte)
- Serial.flush() function does not empty the input buffer. It is only relevant when the Arduino is sending data and its purpose is to block the Arduino until all outgoing the data has been sent.
Transmit and Receive text
Transmit numbers continuously as text with one sec in between:
#include <SoftwareSerial.h>
SoftwareSerial HC12(11, 10); // HC-12 TX Pin, HC-12 RX Pin
int x = 100;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup() {
HC12.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
x = x + 1;
HC12.println(x);
}
}
and receive it using
#include <SoftwareSerial.h>
SoftwareSerial HC12(11, 10); // HC-12 TX Pin, HC-12 RX Pin
void setup() {
Serial.begin(9600);
HC12.begin(9600);
}
void loop() {
if(HC12.available()) {
String texto = HC12.readStringUntil('\n');
Serial.println(texto);
}
}
(Source: https://community.appinventor.mit.edu/t/radio-frequency-hc-12-arduino-bluetooth-hc-06/60935/3)
Transmit and Receive floating point numbers
The protocols transmit characters, only. Thus, if needed to transmit floating point number or any other types, it need to be casted to characters first. It might be beneficial, if only a small amount of data need to be transmitted. Eg. a char is 8 bits, and so numbers from 0-255 can be submitted using one character or "two hexadecimals"; FF = 11111111 = 255 . Thus, the numbers need to be scaled.
https://forum.arduino.cc/t/transferring-float-data-via-hc12/515156/8
#include <SoftwareSerial.h>
SoftwareSerial HC12(11, 10); // HC-12 TX Pin, HC-12 RX Pin
void setup() {
Serial.begin(9600);
HC12.begin(9600);
}
void loop(){
float x = 999.99;
byte* ptr = (byte*) &x;
for (int i = 0; i<4; i++) {
HC12.println((int)ptr[i], HEX);
}
delay(1000);
}
Version 2.
#include <SoftwareSerial.h>
SoftwareSerial HC12(11, 10); // RX, TX
//using 'union'to store a float and a uint8_t array of the same size as a float in the same memory location
union{
float num;
uint8_t bytes[sizeof(float)];
} f_tx;
//
void setup() {
Serial.begin(9600);
HC12.begin (9600);
f_tx.num=0.0; //initialiase float variable
}
void loop() {
f_tx.num = f_tx.num + 1.2;
//using size of float as start byte
HC12.write(sizeof(float));
//set float bytes one by one using a 'for' loop. delay was commented out as optional
for(uint8_t i=0; i<sizeof(float);++i){
HC12.write(f_tx.bytes[i]);
//delay(100);
}
//Serial.print("f_tx.num = ");
//Serial.println(f_tx.num,DEC);
delay(100);
}
Receive floating point number
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 10); // RX, TX
//using 'union'to store a float and a uint8_t array of the same size as a float in the same memory location
union {
float num;
uint8_t bytes[sizeof(float)];
} f_rx;
uint8_t i, r_float;
void setup() {
Serial.begin(9600);
mySerial.begin (9600);
}
void loop() {
byte data;
if (mySerial.available()) {
//read data from RX buffer
data = mySerial.read();
//check of data if data is a float start byte (determined be flag r_float AND data = sizeof(float))
if (data == sizeof(float) && r_float == 0) {
f_rx.num = 0.0; //reset rx float variable
r_float = 1; //set flag
i = 0; //reset byte counter
}
//flag was set ie receiving data is part of a float
else if (r_float == 1) {
//if byte counter is less than sizeof(float), add data to array
if (i < sizeof(float)) {
f_rx.bytes[i] = data;
++i;
}
//all float bytes received print out
else {
Serial.print("f_rx.num = ");
Serial.println(f_rx.num, DEC);
r_float = 0;
}
}
//float start byte not received. therefore just print out received data
else {
Serial.println(data, DEC);
}
}
}
Transmit Tx
Receive Rx
USB - TTL (Serial) interface
6-pin FT232RL
With 1 m cable.
- Black: GND
- Blue: CTS
- Red: VCC
- Green: TXD
- White: RXD
- Yellow: RTS
6-pin CP2102 bipolaarne RS232 RS485
5-pin PL2303HX
The cheapest TTL converter.
DFRobot v2.0 (CP210x)
TTL chip: Silicon Laboratories CP210x. Needs dedicate drivers which are now distributed with 2.6 series kernels, and should be compiled and part of the default installation for most modern Linux distributions. Pins
- GND
- 5V
- RTS - Request to Send. No need to connect.
- TXD -> to RXD
- RXD -> to TXD
- NC - not connected. No need to connect.
- NC - not connected. No need to connect.
Linux:
minicom. Get the portsudo dmesg | grep ttyand use minicom:sudo minicom -b 9600 -o -D /dev/ttyUSB0. UseCtrl+A+n(x2) to get the timestamp to every line, or directly from the command linesudo minicom -b 9600 -o -D /dev/ttyUSB0 -O timestamp=extended.sudo minicom -b 9600 -o -D /dev/ttyUSB0 -O timestamp=extended -C capturefile.logto log the data. Appends to the end of the file.
tio -b 9600 /dev/ttyUSB0
Minicom short tutoria
- Ctrl+A+x: exit
- Ctrl+A+n: timestamp
- Ctrl+A+L: Log the output
Antenna
IPEX20279-001E-03 / (Hirose) U.FI (U.FL) connector.
Helical antenna.
Design software
DIY Yagi
- https://www.instructables.com/DIY-Yagi-Antenna-for-LoRa/ and https://www.youtube.com/watch?v=gA5SCXw_E1Q
- https://www.slideshare.net/slideshow/yagi-antenna-design-and-433mhz-antenna-design-examplepdf/253836272
- Not a yagi https://www.instructables.com/433-MHz-Coil-loaded-antenna/
References
https://forum.arduino.cc/t/serial-input-basics-updated/382007/2