0% found this document useful (0 votes)
175 views25 pages

Arduino and HC-12 Long Range Wireless Communication Module - HowToMechatronics

The document describes how to use an HC-12 wireless communication module to enable long range communication between Arduino boards over distances of up to 1.8km, providing code examples for basic wireless data transmission between two modules and controlling a stepper motor wirelessly based on sensor input. It also explains how to configure the modules' communication channels and baud rates using AT commands sent over serial.

Uploaded by

José Manuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
175 views25 pages

Arduino and HC-12 Long Range Wireless Communication Module - HowToMechatronics

The document describes how to use an HC-12 wireless communication module to enable long range communication between Arduino boards over distances of up to 1.8km, providing code examples for basic wireless data transmission between two modules and controlling a stepper motor wirelessly based on sensor input. It also explains how to configure the modules' communication channels and baud rates using AT commands sent over serial.

Uploaded by

José Manuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

(http://howtomechatronics.

com)

! WHAT'S NEW? " How a Capacitor Works - Capacitor Physics and Applications (http://howtomechatronics.co… $
(https://www.youtube.com/user/DejanNedelkovski)
How RFID Works and How To Make an Arduino based RFID Door Lock (http://howtomechatro…

+ (https://plus.google.com/+Howtomechatronics)
8x8 LED Matrix MAX7219 Tutorial with Scrolling Text & Android Control via Bluetooth (http:/…

& (https://www.facebook.com/howtomechatronics/)
Arduino and HC-12 Long Range Wireless Communication Module (http://howtomechatronics…

Follow me on: ()

Home (http://howtomechatronics.com) ∠
Tutorials (http://howtomechatronics.com/category/tutorials/) ∠ Arduino Tutorials

(http://howtomechatronics.com/category/tutorials/arduino/)

Arduino and HC-12 Long Range Wireless Communication Module


( Dejan Nedelkovski (http://howtomechatronics.com/author/howtom12_wp/) ) July 12, 2017

* Arduino Tutorials (http://howtomechatronics.com/category/tutorials/arduino/)

In this Arduino tutorial we will learn how to use the HC-12 wireless serial communication module which is capable
of making a long range wireless communication between multiple Arduino boards, with distances up to 1.8km. You
can watch the following video or read the written tutorial below for more details.

Arduino and HC-12 Long Range Wireless Communication Module


Overview

For this tutorial I made two basic examples explaining the how to connect the HC-12 module and make a basic com-
munication between two Arduinos and an additional example where using an accelerometer sensor at the first Ar-
duino I wirelessly control the position of the stepper at the second Arduino.

HC-12 Wireless Communication Module


First let’s take a closer look at the HC-12 wireless serial port communication module. Here are some specification:

Its wireless working frequency band is from 433.4 MHz to 473.0 MHz

It has a total of 100 channels with a stepping of 400 KHz between each channel

Transmitting power is from -1dBm (0.79mW) to 20dBm (100mW)

Receiving sensitivity is from -117dBm (0.019pW) to -100dBm (10pW).

These values actually depend on the selected Serial and Over-the-Air Baud Rate as seen in the table.
The HC-12 module has a microcontroller which actually doesn’t have to be programmed by the user. For configur-
ing the module we simply use AT commands, which can be sent from an Arduino, a PC, or any other microcontroller
using the serial port. For entering the AT command mode we just have to set the “Set” pin of the module to a low
logic level.

Arduino and HC-12


Now let’s connect the HC-12 module to the Arduino and make the first example. Here’s the circuit schematics. The
operating voltage of the module is from 3.2 V to 5.5 V and for more stable work it is recommended to use a decou-
pling capacitor and an external power supply. However, I used the PC USB as power for all three examples in this
tutorial and didn’t have any problem with it.

(http://howtomechatronics.com/wp-content/uploads/2017/07/Arduino-and-HC-12-Circuit-Schematic.png?x57244)
I connected the first module to an Arduino UNO and the second module to an Arduino MEGA, but of course, you
can use any board you want.

You can get the components needed for this Arduino Tutorial from the links below:

HC-12 Wireless Communication Module …………… Amazon (http://amzn.to/2sQgJcb)

Arduino Board …………………………………………………. Amazon


(http://howtomechatronics.com/recommends/arduino-mega-board-amazon/)

Breadboard and Jump Wires ……………………………. Amazon


(http://howtomechatronics.com/recommends/breadboard-jumper-wires-kit-amazon/)

*Please note: These are affiliate links. I may make a commission if you buy the components through these links.
I would appreciate your support in this way!

Example 01 – Arduino Code

Here’s the Arduino code for the first example, a basic communication between the two modules using the Serial
Monitor.

1. /* Arduino Long Range Wireless Communication using HC-12


2. Example 01
3. by Dejan Nedelkovski, www.HowToMechatronics.com
4. */
5.
6. #include <SoftwareSerial.h>
7.
8. SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
9.
10. void setup() {
11. Serial.begin(9600); // Serial port to computer
12. HC12.begin(9600); // Serial port to HC12
13.
14. }
15.
16. void loop() {
17. while (HC12.available()) { // If HC-12 has data
18. Serial.write(HC12.read()); // Send the data to Serial monitor
19. }
20. while (Serial.available()) { // If Serial monitor has data
21. HC12.write(Serial.read()); // Send that data to HC-12
22. }
23. }

The same code is used for both Arduinos. We can connect the two Arduinos on two separate computers but also
we can use a single computer.
In that case, once we connect the first Arduino to the computer, we need to select the model and the COM port and
upload the code to the Arduino. Then we connect the second Arduino and we have to start the Arduino IDE again in
order to be able to select the other COM port to which our second Arduino is connected, and then upload the same
code.

So once we have the two Arduino IDEs running we can start the serial monitors and test whether the communica-
tion works properly. Anything we type in the serial monitor will be sent from one to the other Arduino.

How the code works: So once we type something in the serial monitor and click the Send button, at the first Ar-
duino, the while loop with the Serial.available() function will become true and using the HC12.write() function we will
send the data from the serial monitor to the HC-12 module. This module will transfer the data wirelessly to the sec-
ond HC-12 module, so at the second Arduino the while loop with the HC12.available() function will become true and
using the Serial.write() function the data will be sent to the serial monitor.

We can use the same code for sending AT Commands and configuring the module parameters. All we have to do is
connect the “Set” pin of the module to Ground or any digital pin of the Arduino and set the pin to low logic level.
To test whether we have successfully enter the mode, in the serial monitor we can type “AT” and we should get a re-
sponse message “OK”. There are total of 12 AT Commands, and they are used for changing various parameters like
the baud rate, the channel, the transmitting power etc. For example, if we type “AT+B38400” the baud rate of the
module will be set to 38400.

AT Commands:

1. AT – Test command.

Example: Send “AT” to module, and the module returns “OK”.

2. AT+Bxxxx – Change the serial port baud rate.

Available baud rates: 1200 bps, 2400 bps, 4800 bps, 9600 bps, 19200 bps, 38400 bps, 57600 bps, and 115200 bps.
Default: 9600 bps.

Example: Send “AT+B38400” to module, and the module returns “OK+B19200”.

3. AT+Cxxxx – Change wireless communication channel, from 001 to 100.

Default: Channel 001, with working frequency of 433.4MHz. Each next channel is 400KHz higher.

Example: If we want to set the module to channel 006, we need to send “AT+C006” command to the module, and
the module will return “OK+C006”. The new working frequency will be 435.4MHz.

Example 02

Now let’s move the second example. Here we will use two push buttons for selecting different communication
channels and see a different method of storing the incoming data.
Note: The “Set” pins of both HC-12 modules are connected to the pins number 6 of the two Arduinos and the two
buttons, at the first Arduino, to the pins 4 and 3.

First Arduino code:

1. /* Arduino Long Range Wireless Communication using HC-12


2. Example 02 - Changing channels using push buttons - Buttons side
3. by Dejan Nedelkovski, www.HowToMechatronics.com
4. */
5.
6. #include <SoftwareSerial.h>
7.
8. #define setPin 6
9. #define button1 4
10. #define button2 3
11.
12. SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
13.
14. byte incomingByte;
15. String readBuffer = "";
16.
17. int button1State = 0;
18. int button1Pressed = 0;
19. int button2State = 0;
20. int button2Pressed = 0;
21.
22. void setup() {
23. Serial.begin(9600); // Open serial port to computer
24. HC12.begin(9600); // Open serial port to HC12
25. pinMode(setPin, OUTPUT);
26. pinMode(button1, INPUT);
27. pinMode(button2, INPUT);
28. digitalWrite(setPin, HIGH); // HC-12 normal, transparent mode
29. }
30.
31. void loop() {
32. // ==== Storing the incoming data into a String variable
33. while (HC12.available()) { // If HC-12 has data
34. incomingByte = HC12.read(); // Store each icoming byte from HC-12
35. readBuffer += char(incomingByte); // Add each byte to ReadBuffer string variable
36. }
37. delay(100);
38. // ==== Sending data from one HC-12 to another via the Serial Monitor
39. while (Serial.available()) {
40. HC12.write(Serial.read());
41. }
42.
43. // ==== If button 1 is pressed, set the channel 01
44. button1State = digitalRead(button1);
45. if (button1State == HIGH & button1Pressed == LOW) {
46. button1Pressed = HIGH;
47. delay(20);
48. }
49. if (button1Pressed == HIGH) {
50. HC12.print("AT+C001"); // Send the AT Command to the other module
51. delay(100);
52. //Set AT Command Mode
53. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
54. delay(100); // Wait for the HC-12 to enter AT Command mode
55. HC12.print("AT+C001"); // Send AT Command to HC-12
56. delay(200);
57. while (HC12.available()) { // If HC-12 has data (the AT Command response)
58. Serial.write(HC12.read()); // Send the data to Serial monitor
59. }
60. Serial.println("Channel successfully changed");
61. digitalWrite(setPin, HIGH); // Exit AT Command mode
62. button1Pressed = LOW;
63. }
64.
65. // ==== If button 2 is pressed, set the channel 02
66. button2State = digitalRead(button2);
67. if (button2State == HIGH & button2Pressed == LOW) {
68. button2Pressed = HIGH;
69. delay(100);
70. }
71. if (button2Pressed == HIGH) {
72. HC12.print("AT+C002"); // Send the AT Command to the other module
73. delay(100);
74. //Set AT Command Mode
75. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
76. delay(100); // Wait for the HC-12 to enter AT Command mode
77. HC12.print("AT+C002"); // Send AT Command to HC-12
78. delay(200);
79. while (HC12.available()) { // If HC-12 has data (the AT Command response)
80. Serial.write(HC12.read()); // Send the data to Serial monitor
81. }
82. Serial.println("Channel successfully changed");
83. digitalWrite(setPin, HIGH);
84. button2Pressed = LOW;
85. }
86. checkATCommand();
87. readBuffer = ""; // Clear readBuffer
88. }
89. // ==== Custom function - Check whether we have received an AT Command via the Serial Monitor
90. void checkATCommand () {
91. if (readBuffer.startsWith("AT")) { // Check whether the String starts with "AT"
92. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
93. delay(200); // Wait for the HC-12 to enter AT Command mode
94. HC12.print(readBuffer); // Send AT Command to HC-12
95. delay(200);
96. while (HC12.available()) { // If HC-12 has data (the AT Command response)
97. Serial.write(HC12.read()); // Send the data to Serial monitor
98. }
99. digitalWrite(setPin, HIGH); // Exit AT Command mode
100. }
101. }

Second Arduino code:

1. /* Arduino Long Range Wireless Communication using HC-12


2. Example 02 - Changing channels using push buttons
3. by Dejan Nedelkovski, www.HowToMechatronics.com
4. */
5.
6. #include <SoftwareSerial.h>
7.
8. #define setPin 6
9.
10. SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
11.
12. byte incomingByte;
13. String readBuffer = "";
14.
15. void setup() {
16. Serial.begin(9600); // Open serial port to computer
17. HC12.begin(9600); // Open serial port to HC12
18. pinMode(setPin, OUTPUT);
19. digitalWrite(setPin, HIGH); // HC-12 normal mode
20. }
21.
22. void loop() {
23. // ==== Storing the incoming data into a String variable
24. while (HC12.available()) { // If HC-12 has data
25. incomingByte = HC12.read(); // Store each icoming byte from HC-12
26. readBuffer += char(incomingByte); // Add each byte to ReadBuffer string variable
27. }
28. delay(100);
29. // ==== Sending data from one HC-12 to another via the Serial Monitor
30. while (Serial.available()) {
31. HC12.write(Serial.read());
32. }
33. // === If button 1 is pressed, set channel 01
34. if (readBuffer == "AT+C001") {
35. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
36. delay(100); // Wait for the HC-12 to enter AT Command mode
37. HC12.print(readBuffer); // Send AT Command to HC-12 ("AT+C001")
38. delay(200);
39. while (HC12.available()) { // If HC-12 has data (the AT Command response)
40. Serial.write(HC12.read()); // Send the data to Serial monitor
41. }
42. Serial.println("Channel successfully changed");
43. digitalWrite(setPin, HIGH); // Exit AT Command mode
44. readBuffer = "";
45. }
46. // === If button 2 is pressed, set channel 02
47. if (readBuffer == "AT+C002") {
48. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
49. delay(100); // Wait for the HC-12 to enter AT Command mode
50. HC12.print(readBuffer); // Send AT Command to HC-12
51. delay(200);
52. while (HC12.available()) { // If HC-12 has data (the AT Command response)
53. Serial.write(HC12.read()); // Send the data to Serial monitor
54. }
55. Serial.println("Channel successfully changed");
56. digitalWrite(setPin, HIGH); // Exit AT Command mode
57.
58. readBuffer = "";
59. }
60. checkATCommand();
61. readBuffer = ""; // Clear readBuffer
62. }
63. // ==== Custom function - Check whether we have received an AT Command via the Serial Monitor
64. void checkATCommand () {
65. if (readBuffer.startsWith("AT")) { // Check whether the String starts with "AT"
66. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
67. delay(100); // Wait for the HC-12 to enter AT Command mode
68. HC12.print(readBuffer); // Send AT Command to HC-12
69. delay(200);
70. while (HC12.available()) { // If HC-12 has data (the AT Command response)
71. Serial.write(HC12.read()); // Send the data to Serial monitor
72. }
73. digitalWrite(setPin, HIGH); // Exit AT Command mode
74. }
75. }

Description of the codes:

So, first we need to define the pins and set the “Set” pin to high logic level in order the module to work in normal,
transparent mode. With the first while loop we store the incoming data into a String variable, so we can better han-
dle it.

1. // ==== Storing the incoming data into a String variable


2. while (HC12.available()) { // If HC-12 has data
3. incomingByte = HC12.read(); // Store each icoming byte from HC-12
4. readBuffer += char(incomingByte); // Add each byte to ReadBuffer string variable
5. }

The incoming data always comes one byte at a time, so for example if we send the string “Test123” from second Ar-
duino, this while loop will do 7 iterations. Each iteration, using the HC12.read() function we will read each incoming
byte or character and add it to the String variable named “readBuffer”.
Next let’s see how we can change the communication channel using the first push button. So if we press the first
push button, using the HC12.print() function we will send the string “AT+C001” to the HC-12 module or to the sec-
ond Arduino.

1. if (button1Pressed == HIGH) {
2. HC12.print("AT+C001"); // Send the AT Command to the other module
3. delay(100);
4. //Set AT Command Mode
5. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
6. delay(100); // Wait for the HC-12 to enter AT Command mode
7. HC12.print("AT+C001"); // Send AT Command to HC-12
8. delay(200);
9. while (HC12.available()) { // If HC-12 has data (the AT Command response)
10. Serial.write(HC12.read()); // Send the data to Serial monitor
11. }
12. Serial.println("Channel successfully changed");
13. digitalWrite(setPin, HIGH); // Exit AT Command mode
14. button1Pressed = LOW;
15. }

When this string will be received at the second Arduino, we will set the HC-12 module into AT command mode, and
then write the same string “AT+C001” to it which will set the module to communication channel number one.

1. // At the second Arduino


2.
3. // === If button 1 is pressed, set channel 01
4. if (readBuffer == "AT+C001") {
5. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
6. delay(100); // Wait for the HC-12 to enter AT Command mode
7. HC12.print(readBuffer); // Send AT Command to HC-12 ("AT+C001")
8. delay(200);
9. while (HC12.available()) { // If HC-12 has data (the AT Command response)
10. Serial.write(HC12.read()); // Send the data to Serial monitor
11. }
12. Serial.println("Channel successfully changed");
13. digitalWrite(setPin, HIGH); // Exit AT Command mode
14. readBuffer = "";
15. }

We use the next while loop to print the response message from the HC-12 module whether the channel has been
successfully changed.

1. while (HC12.available()) { // If HC-12 has data (the AT Command response)


2. Serial.write(HC12.read()); // Send the data to Serial monitor
3. }

Back at the first Arduino, we do the same procedure of sending the AT command to the first HC-12 module. In the
same way we, using the pushing the second button, we set the communication channel number two. So using this
method we can select, at any time, with which HC-12 module we will communicate.

At the end, the checkATCommand() custom function, checks whether the received message is an AT command, by
checking whether the string starts with “AT”. If so, the module enters the AT command mode and executes the
command.
1. // ==== Custom function - Check whether we have received an AT Command via the Serial Monitor
2. void checkATCommand () {
3. if (readBuffer.startsWith("AT")) { // Check whether the String starts with "AT"
4. digitalWrite(setPin, LOW); // Set HC-12 into AT Command mode
5. delay(200); // Wait for the HC-12 to enter AT Command mode
6. HC12.print(readBuffer); // Send AT Command to HC-12
7. delay(200);
8. while (HC12.available()) { // If HC-12 has data (the AT Command response)
9. Serial.write(HC12.read()); // Send the data to Serial monitor
10. }
11. digitalWrite(setPin, HIGH); // Exit AT Command mode
12. }
13. }

HC-12 Wireless Communication: Stepper Motor Control using an Accelerometer

Now let’s take a look at the third example. Here we control the position of the stepper motor at the second Arduino,
using the accelerometer module at the first Arduino.

The circuit also contains a microswitch for finding the initial position of the stepper motor at 0 degrees.
(http://howtomechatronics.com/wp-content/uploads/2017/07/HC-12-Wireless-Communication-Stepper-Motor-Con-
trol-using-an-Accelerometer-Circuit-Schematic.png?x57244)

You can get the components needed for this example from the links below:

HC-12 Wireless Communication Module …………… Amazon (http://amzn.to/2sQgJcb)

GY-80 Board with ADXL345 Accelerometer ………. Amazon (http://amzn.to/2teTGHC)

A4988 Stepper Motor Driver …………………………….. Amazon


(http://howtomechatronics.com/recommends/a4988-driver-amazon/)

Stepper Motor NEMA 17 …………………………………… Amazon


(http://howtomechatronics.com/recommends/stepper-motor-amazon/)

Arduino Board …………………………………………………. Amazon


(http://howtomechatronics.com/recommends/arduino-mega-board-amazon/)

Breadboard and Jump Wires ……………………………. Amazon


(http://howtomechatronics.com/recommends/breadboard-jumper-wires-kit-amazon/)

*Please note: These are affiliate links. I may make a commission if you buy the components through these links.
I would appreciate your support in this way!

Note here that I already have detailed tutorials on how to connect and use both the accelerometer (http://howto-
mechatronics.com/how-it-works/electrical-engineering/mems-accelerometer-gyrocope-magnetometer-arduino/)
and the stepper motor (http://howtomechatronics.com/tutorials/arduino/how-to-control-stepper-motor-with-
a4988-driver-and-arduino/), so for this example I will only explain the HC-12 part of the code.

First Arduino – Transmitter code:

1. /* Arduino Long Range Wireless Communication using HC-12


2. Example 03 - Stepper Motor Control using Accelerometer - Transmitter, Accelerometer
3. by Dejan Nedelkovski, www.HowToMechatronics.com
4. */
5.
6. #include <SoftwareSerial.h>
7. #include <Wire.h>
8.
9. SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
10.
11. float angle;
12. int lastAngle = 0;
13. int count = 0;
14. int angleSum = 0;
15.
16. //--- Accelerometer Register Addresses
17. #define Power_Register 0x2D
18. #define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
19. #define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
20. #define Y_Axis_Register_DATAY0 0x34
21. #define Y_Axis_Register_DATAY1 0x35
22. #define Z_Axis_Register_DATAZ0 0x36
23. #define Z_Axis_Register_DATAZ1 0x37
24. int ADXAddress = 0x53; //Device address in which is also included the 8th bit for selecting the
mode, read in this case.
25. int X0, X1, X_out;
26. int Y0, Y1, Y_out;
27. int Z1, Z0, Z_out;
28. float Xa, Ya, Za;
29.
30. void setup() {
31. HC12.begin(9600); // Open serial port to HC12
32. Wire.begin(); // Initiate the Wire library
33. Serial.begin(9600);
34. delay(100);
35.
36. Wire.beginTransmission(ADXAddress);
37. Wire.write(Power_Register); // Power_CTL Register
38. // Enable measurement
39. Wire.write(8); // Bit D3 High for measuring enable (0000 1000)
40. Wire.endTransmission();
41. }
42. void loop() {
43. // X-axis
44. Wire.beginTransmission(ADXAddress); // Begin transmission to the Sensor
45. //Ask the particular registers for data
46. Wire.write(X_Axis_Register_DATAX0);
47. Wire.write(X_Axis_Register_DATAX1);
48. Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
49. Wire.requestFrom(ADXAddress, 2); // Request the transmitted two bytes from the two registers
50. if (Wire.available() <= 2) { //
51. X0 = Wire.read(); // Reads the data from the register
52. X1 = Wire.read();
53. /* Converting the raw data of the X-Axis into X-Axis Acceleration
54. - The output data is Two's complement
55. - X0 as the least significant byte
56. - X1 as the most significant byte */
57. X1 = X1 << 8;
58. X_out = X0 + X1;
59. Xa = X_out / 256.0; // Xa = output value from -1 to +1, Gravity acceleration acting on the
X-Axis
60. }
61. //Serial.print("Xa= ");
62. //Serial.println(X_out);
63.
64. // Y-Axis
65. Wire.beginTransmission(ADXAddress);
66. Wire.write(Y_Axis_Register_DATAY0);
67. Wire.write(Y_Axis_Register_DATAY1);
68. Wire.endTransmission();
69. Wire.requestFrom(ADXAddress, 2);
70. if (Wire.available() <= 2) {
71. Y0 = Wire.read();
72. Y1 = Wire.read();
73. Y1 = Y1 << 8;
74. Y_out = Y0 + Y1;
75. Ya = Y_out / 256.0;
76. }
77.
78. // Combine X and Y values for getting the angle value from 0 to 180 degrees
79. if (Y_out > 0) {
80. angle = map(Y_out, 0, 256, 90, 0);
81. }
82. else if (Y_out < 0) {
83. angle = map(Y_out, 256, 0, 90, 0);
84. angle = 90 - angle;
85. }
86. if (X_out < 0 & Y_out < 0) {
87. angle = 180;
88. }
89. if (X_out < 0 & Y_out >0) {
90. angle = 0;
91. }
92.
93. // float to int
94. int angleInt = int(angle);
95. // Makes 100 accelerometer readings and sends the average for smoother result
96. angleSum = angleSum + angleInt;
97. count++;
98. if (count >= 100) {
99. angleInt = angleSum / 100;
100. angleSum = 0;
101. count = 0;
102. // Some more smoothing of acceleromter reading - sends the new angle only if it differes
from the previous one by +-2
103. if (angleInt > lastAngle + 2 || angleInt < lastAngle - 2) {
104. Serial.println(angleInt);
105. String angleString = String(angleInt);
106. //sends the angle value with start marker "s" and end marker "e"
107. HC12.print("s" + angleString + "e");
108. delay(10);
109. lastAngle = angleInt;
110. angleSum = 0;
111. count = 0;
112. }
113. }
114. }

Second Arduino – Receiver code:

1. /* Arduino Long Range Wireless Communication using HC-12


2. Example 03 - Stepper Motor Control using Accelerometer - Receiver, Stepper Motor
3.
4. by Dejan Nedelkovski, www.HowToMechatronics.com
5. */
6. #include <SoftwareSerial.h>
7.
8. SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
9.
10. char incomingByte;
11. String readBuffer = "";
12.
13. // defines pins numbers
14. const int dirPin = 4;
15. const int stepPin = 3;
16. const int button = 2;
17.
18. int currentAngle = 0;
19. int lastAngle = 0;
20. int rotate = 0;
21.
22. void setup() {
23. Serial.begin(9600); // Open serial port to computer
24. HC12.begin(9600); // Open serial port to HC12
25.
26. // Sets the two pins as Outputs
27. pinMode(dirPin, OUTPUT);
28. pinMode(stepPin, OUTPUT);
29. // Microswitch input, with internal pull-up resistor activated
30. pinMode(button, INPUT_PULLUP);
31. delay(10);
32. digitalWrite(dirPin, HIGH);
33. boolean startingPosition = true;
34. while (startingPosition) {
35. digitalWrite(stepPin, HIGH);
36. delayMicroseconds(200);
37. digitalWrite(stepPin, LOW);
38. delayMicroseconds(200);
39. if (digitalRead(button) == LOW) {
40. startingPosition = false;
41. }
42. }
43. delay(100);
44. }
45. void loop() {
46. readBuffer = "";
47. boolean start = false;
48. // Reads the incoming angle
49. while (HC12.available()) { // If HC-12 has data
50. incomingByte = HC12.read(); // Store each icoming byte from HC-12
51. delay(5);
52. // Reads the data between the start "s" and end marker "e"
53. if (start == true) {
54. if (incomingByte != 'e') {
55. readBuffer += char(incomingByte); // Add each byte to ReadBuffer string variable
56. }
57. else {
58. start = false;
59. }
60. }
61. // Checks whether the received message statrs with the start marker "s"
62. else if ( incomingByte == 's') {
63. start = true; // If true start reading the message
64. }
65. }
66. // Converts the string into integer
67. currentAngle = readBuffer.toInt();
68. // Makes sure it uses angles between 0 and 180
69. if (currentAngle > 0 && currentAngle < 180) {
70. // Convert angle value to steps (depending on the selected step resolution)
71. // A cycle = 200 steps, 180deg = 100 steps ; Resolution: Sixteenth step x16
72. currentAngle = map(currentAngle, 0, 180, 0, 1600);
73. //Serial.println(currentAngle); // Prints the angle on the serial monitor
74. digitalWrite(dirPin, LOW); // Enables the motor to move in a particular direction
75. // Rotates the motor the amount of steps that differs from the previous positon
76. if (currentAngle != lastAngle) {
77. if (currentAngle > lastAngle) {
78. rotate = currentAngle - lastAngle;
79. for (int x = 0; x < rotate; x++) {
80. digitalWrite(stepPin, HIGH);
81. delayMicroseconds(400);
82. digitalWrite(stepPin, LOW);
83. delayMicroseconds(400);
84. }
85. }
86. // rotate the other way
87. if (currentAngle < lastAngle) {
88. rotate = lastAngle - currentAngle;
89. digitalWrite(dirPin, HIGH); //Changes the rotations direction
90. for (int x = 0; x < rotate; x++) {
91. digitalWrite(stepPin, HIGH);
92. delayMicroseconds(400);
93. digitalWrite(stepPin, LOW);
94. delayMicroseconds(400);
95. }
96. }
97. }
98. lastAngle = currentAngle; // Remembers the current/ last positon
99. }
100. }

Description of the codes:

So first we defining the pins and initializing the modules in the setup section. Then we read the values of the X and
Y axis of the accelerometer and map them to a values from 0 to 180 degrees. The values coming from the ac-
celerometer can sometimes be unstable or shake, so for smoothing the result I used the average value of one hun-
dred readings.

1. // Makes 100 accelerometer readings and sends the average for smoother result
2. angleSum = angleSum + angleInt;
3. count++;
4. if (count >= 100) {
5. angleInt = angleSum / 100;
6. angleSum = 0;
7. count = 0;
8. // Some more smoothing of acceleromter reading - sends the new angle only if it differes
from the previous one by +-2
9. if (angleInt > lastAngle + 2 || angleInt < lastAngle - 2) {
10. Serial.println(angleInt);
11. String angleString = String(angleInt);
12. //sends the angle value with start marker "s" and end marker "e"
13. HC12.print("s" + angleString + "e");
14. delay(10);
15. lastAngle = angleInt;
16. angleSum = 0;
17. count = 0;
18. }
19. }

For even further smoothing I will send the new value of the angle only if it differs from the previous by 2.

Note here that when sending the angle to the HC-12 module, I’m also sending the character “s” in front, and the
character “e” after, which will help me when receiving the data at the second Arduino.

At the second Arduino we wait until the start marker “s” comes, then we read the value of the angle until the end
marker “e” arrive. This way we are sure that we will receive only the value of the angle.

1. // Reads the incoming angle


2. while (HC12.available()) { // If HC-12 has data
3. incomingByte = HC12.read(); // Store each icoming byte from HC-12
4. delay(5);
5. // Reads the data between the start "s" and end marker "e"
6. if (start == true) {
7. if (incomingByte != 'e') {
8. readBuffer += char(incomingByte); // Add each byte to ReadBuffer string variable
9. }
10. else {
11. start = false;
12. }
13. }
14. // Checks whether the received message statrs with the start marker "s"
15. else if ( incomingByte == 's') {
16. start = true; // If true start reading the message
17. }
18. }

Then we convert the value to integer, and map the value from 0 to 1600 steps, which corresponds to the selected
sixteenth step resolution at the A4988 stepper driver. Then we rotate the stepper motor to the current angle.

So that would be all for this Arduino tutorial. Feel free to ask any question in the comments section below.

EasyEDA: Ideas for Circuit Design, Innovation for Electronics Access


(http://easyeda.com)

Free Circuit Design: Schematic - Simulation - PCB Layout - Gerber Viewer


(https://easyeda.com/editor)

Cheapest PCB Prototype: Only $2 for 10pcs 10×10cm PCBs, 24 hours Quick Turn, DHL Delivery in 3 Days
(https://easyeda.com/order)

Accelerometer (http://howtomechatronics.com/tag/accelerometer/)

Arduino Tutorial (http://howtomechatronics.com/tag/arduino-tutorial/)

HC-12 (http://howtomechatronics.com/tag/hc-12/)
Serial Communication (http://howtomechatronics.com/tag/serial-communication/)

Stepper Motor (http://howtomechatronics.com/tag/stepper-motor/)

Wireless (http://howtomechatronics.com/tag/wireless/)

RELATED POSTS

ULTRASONIC SENSOR HC-SR04 AND ARDUINO TUTORIAL (HTTP://HOWTOMECHATRONICS.COM/TUTORIALS/ARDUINO/ULTRASONIC-SENSOR-HC-SR04/)

( Dejan Nedelkovski (http://howtomechatronics.com/author/howtom12_wp/) ) July 26, 2015

+ 83 (http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/#comments)
(http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/)
ARDUINO WIRELESS COMMUNICATION – NRF24L01 TUTORIAL (HTTP://HOWTOMECHATRONICS.COM/TUTORIALS/ARDUINO/ARDUINO-WIRELESS-
COMMUNICATION-NRF24L01-TUTORIAL/)

( Dejan Nedelkovski (http://howtomechatronics.com/author/howtom12_wp/) ) February 18, 2017

+ 20 (http://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/#comments)
(http://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/)

ARDUINO SD CARD AND DATA LOGGING TO EXCEL TUTORIAL (HTTP://HOWTOMECHATRONICS.COM/TUTORIALS/ARDUINO/ARDUINO-SD-CARD-DATA-


LOGGING-EXCEL-TUTORIAL/)

( Dejan Nedelkovski (http://howtomechatronics.com/author/howtom12_wp/) ) August 25, 2016

+ 17 (http://howtomechatronics.com/tutorials/arduino/arduino-sd-card-data-logging-excel-tutorial/#comments)
(http://howtomechatronics.com/tutorials/arduino/arduino-sd-card-data-logging-excel-tutorial/)
ARDUINO TUTORIAL 03: ANALOG INPUTS (HTTP://HOWTOMECHATRONICS.COM/TUTORIALS/ARDUINO/ANALOG-INPUTS/)

( Dejan Nedelkovski (http://howtomechatronics.com/author/howtom12_wp/) ) February 3, 2015

+ 2 (http://howtomechatronics.com/tutorials/arduino/analog-inputs/#comments)
(http://howtomechatronics.com/tutorials/arduino/analog-inputs/)

L E AV E A R E P LY

Your email address will not be published.

Comment

Name* Email*

Website
SUBMIT

(https://mydevices.com/cayenne/landing/jumpstart-projects-with-cayenne/?
utm_source=howtomechatronics%7Cs&utm_medium=display&utm_campaign=howtomechatronics%20arduino%7Cs)

L AT E S T

ARDUINO AND HC-12 LONG RANGE WIRELESS COMMUNICATION


/ARDUINO-
MODULE
(HTTP://HOWTOMECHATRONICS.COM/TUTORIALS/ARDUINO/ARDUINO-
AND-HC-12-LONG-RANGE-WIRELESS-COMMUNICATION-
MODULE/)

( Dejan Nedelkovski
(http://howtomechatronics.com/author/howtom12_wp/)

) July 12, 2017


POPULAR

Arduino Radar Project


(http://howtomechatronics.com/projects/arduino-
radar-project/)
( Dejan Nedelkovski
(http://howtomechatronics.com/author/howtom12_w
) July 28, 2015
+ 300
(http://howtomechatronics.com/projects/arduino-
radar-project/#comments)

(http://howtomechatronics.com/projects/arduino-radar-project/)

Ultrasonic Sensor HC-SR04


and Arduino Tutorial
(http://howtomechatronics.com/tu
sensor-hc-sr04/)
( Dejan Nedelkovski
(http://howtomechatronics.com/aut
) July 26, 2015
+ 83
(http://howtomechatronics.com/tut
sensor-hc-sr04/#comments)

(http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/)
(http://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-it-with-
arduino/)

Arduino TFT
LCD Touch
Screen
Tutorial
(http://howtomechat
tft-lcd-
touch-
screen-
tutorial/)
( Dejan Nedelkovski
(http://howtomechatr
) December
7, 2015
+ 140
(http://howtomechatr
tft-lcd-touch-screen-

(http://howtomechatronics.com/tutorials/arduino/arduino-tft-lcd-touch-screen-tutorial/)
Get Email Updates!
Signup now and receive an email once I publish new content.

Enter Your Name Enter Your Email Address Sign Up

I will never give away, trade or sell your email address. You can unsubscribe at any time.

DIY & CRAFTS PROJECTS

(http://www.creativityhero.com/diy-crafts/how-to-make-a-modern-
How To Make A Modern Wooden Clock
wooden-clock-diy-project/)

HOW TO MECHATRONICS

HowToMechatronics is an education website in the area of Mechanical, Electrical and Computer Engineering.
Tutorials, Tips, Tricks, How It Works, Projects, Examples, Source Codes, Download files and much more can be
found here.

Copyright © 2017 HowToMechatronics.com. All rights reserved. Terms and Conditions (http://howtomechatronics.com/disclaimer/)

You might also like