Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:55 03 Aug 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 : Newie HC-12 Question

     Page 1 of 2    
Author Message
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 01:52pm 20 Nov 2017
Copy link to clipboard 
Print this post

Hi to all and love the Forum
My question is I have a MME with HC-12 and a Micromite LCD Backpack with HC-12 is there a simple program to send say "temp" from the backpack to the MME I am learning slowly been a long time when I last played with basic
all the best and merry Christmas to all
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 02:33pm 20 Nov 2017
Copy link to clipboard 
Print this post

Hi Macca - welcome.

The HC-12 arranged as two modules on the same channel will perform just like a piece of cable - they really are that easy to work with. There are some fine controls over how the HC-12's work but so long as they are in range they are really trouble free. They can support about 128 channels but most come pre-configured for channel 0 so usually work "out of the box". Have a search around on this forum for some really good threads about them this year.

So let's say you have the HC12's connected to the COM2 serial port on the micromites on each side of your requirement (the transmitting node and the recieving node, say) you simply output data to the port at one end and it will appear in the buffer on the other end.

here is a bit of code to play with which should fire your imagination:

On the transmitting node:

'open the serial port - the manual will tell you what all these numbers mean
'This is called a stream and has a number starting with a # - let's call it #2
Open "COM2:9600,64" As #2
'now go round in a loop
Do
Print #2,"Hello World " + time$ ' print the message and the time to the serial port
Pause 1000' wait for a second
Loop ' and repeat




Now on the recieving node:

Open "COM2:9600,64" As #2 ' open the serial port and call it "#2"
Do
If Loc(#2)<>0 then ' is there some data in the buffer?
Print Input$(Loc(#2),#2); 'if so, get it and print it to the console
endif
Loop


Remember either side could be the reciever or transmitter... both sides can talk to each other so either side could reply to any message.

Then is just down to you what data you want to send and what you want to do with it when it gets to the other side.

There are lots of friendly people here and many are returning to programming after years away so don't worry about asking questions.

 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 10:34pm 20 Nov 2017
Copy link to clipboard 
Print this post

Superb reply, Captain.
Smoke makes things work. When the smoke gets out, it stops!
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 02:52am 21 Nov 2017
Copy link to clipboard 
Print this post

Hi and thank you for your friendly reply
I have don what is mentioned and still no response I suspect one of the HC-12 to be faulty can see pulse going to trx pin with my cro. Set up my SDR. radio and can see pulse being trx out. I will reverse the set up to see if info is being rec the other way
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 06:51am 21 Nov 2017
Copy link to clipboard 
Print this post

IF - and ONLY if - both HC-12's are brand new, they will be on default settings, and should work right out of the box for the purposes of experimentation.

Connect 5v power to both modules.(the HC-12 is unreliable at 3v3)

On the HC-12, TXD is OUTPUT and RXD is INPUT with respect to the module, so if you want to transmit something, you feed serial into GND and RXD. If you want to receive something from the HC-12, you connect to GND and TXD.

It is 50/50 that you have TXD and RXD mixed up - it happens to us all, and after twenty-something years of dealing with COM ports and serial, I am STILL getting that wrong just about daily.
Smoke makes things work. When the smoke gets out, it stops!
 
kiaandre
Newbie

Joined: 21/11/2017
Location: France
Posts: 18
Posted: 09:09am 21 Nov 2017
Copy link to clipboard 
Print this post

Bonjour

Je suis tout nouveau sur le forum

Il y a un très bon article sur le HC-12 sur le lien cidessous

http://www.alselectro.com/hc12---433mhz-long-range-rf.html

A BientotEdited by kiaandre 2017-11-22
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 01:12pm 22 Nov 2017
Copy link to clipboard 
Print this post

Roger I have had the tx and rx the right way but did not try on 5v. Will give it a try tomorrow in the mean time I have orded 4 new HC-12 boards. I have been able to talk to the HC-12 to change parameters but still no go will try 5v.
I will keep you informed as to how it goes
 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 08:35pm 22 Nov 2017
Copy link to clipboard 
Print this post

  kiaandre said   Bonjour

Je suis tout nouveau sur le forum

Il y a un très bon article sur le HC-12 sur le lien cidessous

http://www.alselectro.com/hc12---433mhz-long-range-rf.html

A Bientot



For all us Aussies etc,

  kiaandre said  Hello

I'm new to the forum

There is a very good article on the HC-12 on the link below

http://www.alselectro.com/hc12---433mhz-long-range-rf.html

See you soon[/quote]Edited by Phil23 2017-11-24
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 10:22pm 22 Nov 2017
Copy link to clipboard 
Print this post

  macca said   Roger I have had the tx and rx the right way but did not try on 5v. Will give it a try tomorrow in the mean time I have orded 4 new HC-12 boards. I have been able to talk to the HC-12 to change parameters but still no go will try 5v.
I will keep you informed as to how it goes


I admire your confidence with respect to getting TX and RX round the right way!

Yes, when I tried running HC-12's at 3v3, they were unreliable. The datasheet says you can power them down to 3v2 I think, but I did not have much luck. At 5v, they have ALWAYS worked for me.

Please connect to a 5v tolerant COM port, or use a logic level converter such as these things here. Dirt cheap, and are bi-directional, so will work either way around to convert 3v3 to 5v or 5v to 3v3. You can also just add 1k series resistors between the HC-12 and a 3v3 COM port - that seems to also be perfectly acceptable depending on who you are talking to.
Smoke makes things work. When the smoke gets out, it stops!
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 01:16am 26 Nov 2017
Copy link to clipboard 
Print this post

Hi done some tests and one HC-12 board is faulty I have also orded some Logic level converters again thank you for information I will keep you informed as to how things go when new boards turn up
Regards
John
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 11:50am 14 Jan 2018
Copy link to clipboard 
Print this post

Hi to all
I have received new HC-12 boards and all is running my question is on the tx side I have a DH22 and want to send temp and humidity can someone please give me an idea as to what the tx and rx program should be. I have been playing around with this but the program seems to get confused and the temp and humidity keep swopping around could be a timing problem?
regards
John
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 10:04am 15 Jan 2018
Copy link to clipboard 
Print this post

Hi there.

As the HC12 is expecting 8-bit bytes, if you send it a float number, it will most likely simply ignore it and nothing will go across the link. The serial data needs to be formatted into 8-bit integer ASCII strings, in other words.

Untested, but assuming a 170 MM2 chip:

[code]
DIM FLOAT TV,HV 'Values from DHT22 are returned as floats
DIM TVS$,HVS$ 'Strings to hold the ASCII numbers
OPEN "COM1:9600" AS #1 'HC12 COM port - assuming 9600 baud
DO
HUMID 02,TV,HV 'Suck values from DHT22 sensor on pin2, and stick them into TV and HV
TVS$=STR$(TV):HVS$=STR$(HV) 'Convert the float numbers to ASCII strings
PRINT #1,TVS$,HVS$ 'Send values from DHT22 sensor to HC12 on COM1 as ASCII
PAUSE 1000
LOOP
[/code]

This should send the float numbers as ASCII via the HC12.

You would decode the data at the other end of the link by using VAL such as TV=VAL(TVS$) - that sort of thing. Have a go at working out what the receiver code should be. If you get stuck, I and/or other members will help. Edited by Grogster 2018-01-16
Smoke makes things work. When the smoke gets out, it stops!
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 12:49am 16 Jan 2018
Copy link to clipboard 
Print this post

Hi I will give it a try as the weather is horrible here in WA. again thank you and will keep you posted
regards
John
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 04:52am 16 Jan 2018
Copy link to clipboard 
Print this post

Hi again and sorry to be a pain
Still having problems and I have changed from DH22 to BMP280 on playing around I have sent data from one to the other but gets a bit muddled, program below for tx
TX is 44 pin with HC-12 and RX is 44 pin backpack with HC-12

'Connection to the device is I2C.
'Connect I2C Clock on the Micromite to SCK on the module
'Connect I2C Data on the Micromite to SDI on the module
'Connect power and ground (the device works fine on 3.3V)
'Leave CS and SDO on the module unconnected




option explicit
option default none
'
' BME280 routines and test harness
'
const BME280_ADDRESS = &H76
const BME280_REGISTER_T1 = &H88
const BME280_REGISTER_P1 = &H8E
const BME280_REGISTER_H1 = &HA1
const BME280_REGISTER_H2 = &HE1
const BME280_REGISTER_CHIPID = &HD0
const BME280_REGISTER_CONTROLHUMID = &HF2
const BME280_REGISTER_CONTROL = &HF4
const BME280_REGISTER_PRESSUREDATA = &HF7
const BME280_REGISTER_TEMPDATA = &HFA
const BME280_REGISTER_HUMIDDATA = &HFD
'
dim integer s16=&HFFFFFFFFFFFF0000 , s16b=&H8000
dim integer s12=&HFFFFFFFFFFFFF000 , s12b=&H800
dim integer s8= &HFFFFFFFFFFFFFF00 , s8b=&H80
'
DIM INTEGER T1,T2,T3 'uint16_t, int16_t, int16_t
DIM INTEGER P1,P2,P3,P4,P5,P6,P7,P8,P9 'uint16_t, 8 x int16_t
DIM INTEGER H1,H2,H3,H4,H5,H6 'uint8_t, int16_t , uint8_t, int16_t, int16_t, int8_t
dim INTEGER t_fine 'used to store accurate temp reading from temp conversion for use in pressure and humidity conversions
'*************************************************************************************************
Open "COM2:4800,64" As #2 ' open the first serial port with a speed of 4800 baud
bme280_init
DO
' This is where I am having trouble
'Trying to send to HC-12 temp,pressure,humidity


pause 3000
loop
'
end
'
'***************************************************************************************************
'
function bme280_read_temp() as float
local integer var1,var2,adc_T
local adc%(2)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_TEMPDATA
i2c read BME280_ADDRESS,0,3,adc%()
adc_T=((adc%(0)<<16) OR (adc%(1)<<8) or adc%(2))>>4
var1 = ((((adc_T>>3) - (T1 <<1))) * T2) \ q(11)
var2 = (((((adc_T>>4) - (T1)) * ((adc_T\ q(4)) - (T1))) \ q(12)) * (T3)) \ q(14)
t_fine = var1 + var2
bme280_read_temp = ((t_fine * 5 + 128) \ q(8))/100.0
end function

function bme280_read_pressure() as float
local integer var1, var2, adc_P, p
local adc%(2)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_PRESSUREDATA
i2c read BME280_ADDRESS,0,3,adc%()
adc_P=((adc%(0)<<16) OR (adc%(1)<<8) or adc%(2))>>4
var1 = t_fine - 128000
var2 = var1 * var1 * P6
var2 = var2 + ((var1 * P5)<<17)
var2 = var2 + (P4 << 35)
var1 = ((var1 * var1 * P3)\ q(8)) + ((var1 * P2)<<12)
var1 = ((1<<47)+var1)*P1\ q(33)
if var1 = 0 THEN
bme280_read_pressure = 0' avoid exception caused by division by zero
exit function
endif
p = 1048576 - adc_P
p = (((p<<31) - var2)*3125) \ var1
var1 = (P9 * (p\ q(13)) * (p\ q(13))) \ q(25)
var2 = (P8 * p) \ q(19)
p = ((p + var1 + var2) \ q(8)) + (P7<<4)
bme280_read_pressure = p/25600.0
end function
'
function bme280_read_humidity() as float
local integer v_x1,adc_H
local adc%(1)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_HUMIDDATA
i2c read BME280_ADDRESS,0,2,adc%()
adc_H=(adc%(0)<<8) or adc%(1)
v_x1 = t_fine - 76800
v_x1=(((((adc_H<<14)-((H4)<<20)-(H5*v_x1))+16384)\ q(15))*(((((((v_x1*H6)\ q(10))*(((v_x1*H3)\ q(11))+32768))\ q(10))+2097152)*H2+8192)\ q(14)))
v_x1 = (v_x1 - (((((v_x1 \ q(15)) * (v_x1 \ q(15))) \ q(7)) * (H1)) \ q(4)))
if v_x1< 0 then v_x1 = 0
if v_x1 > 419430400 then v_x1= 419430400
bme280_read_humidity = (v_x1\ q(12)) / 1024.0
end function

sub bme280_init
local i%,cal%(17)
i2c open 400,1000 '400KHz bus speed
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_CHIPID
i2c read BME280_ADDRESS,0,1,i%
if i%<>&H60 then print "Error BME280 not found"
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_T1
i2c read BME280_ADDRESS,0,6,cal%()
T1=cal%(0) OR (cal%(1)<< 8)
T2=cal%(2) OR (cal%(3)<< 8): if T2 and s16b then T2=T2 OR s16 'sign extend if required
T3=cal%(4) OR (cal%(5)<< 8): if T3 and s16b then T3=T3 OR s16
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_P1
i2c read BME280_ADDRESS,0,18,cal%()
P1=cal%(0) OR (cal%(1)<<8)
P2=cal%(2) OR (cal%(3)<<8): if P2 and s16b then P2=P2 OR s16 'sign extend if required
P3=cal%(4) OR (cal%(5)<<8): if P3 and s16b then P3=P3 OR s16
P4=cal%(6) OR (cal%(7)<<8): if P4 and s16b then P4=P4 OR s16
P5=cal%(8) OR (cal%(9)<<8): if P5 and s16b then P5=P5 OR s16
P6=cal%(10) OR (cal%(11)<<8): if P6 and s16b then P6=P6 OR s16
P7=cal%(12) OR (cal%(13)<<8): if P7 and s16b then P7=P7 OR s16
P8=cal%(14) OR (cal%(15)<<8): if P8 and s16b then P8=P8 OR s16
P9=cal%(16) OR (cal%(17)<<8): if P9 and s16b then P9=P9 OR s16
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_H1
i2c read BME280_ADDRESS,0,1,H1
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_H2
i2c read BME280_ADDRESS,0,7,cal%()
H2=cal%(0) OR (cal%(1)<< 8): if H2 and s16b then H2=H2 OR s16 'sign extend if required
H3=cal%(2)
H6=cal%(6): if H6 and s8b then H6=H6 OR s8 'sign extend if required
H4=(cal%(3)<<4) OR (cal%(4) and &H0F): if H4 and s12b then H4=H4 OR s12 'sign extend if required
H5=(cal%(5)<<4) OR (cal%(4)>>4): if H5 and s12b then H5=H5 OR s12
'
i2c write BME280_ADDRESS,0,2,BME280_REGISTER_CONTROLHUMID,&H05 '16x oversampling humidity
i2c write BME280_ADDRESS,0,2,BME280_REGISTER_CONTROL,&HB7 '16x oversampling pressure/temp, normal mode
'
end sub
'
'End CFunction

Program for RX

OPTION AUTORUN ON

CLS
Open "COM2:4800,64" As #2 ' open the serial port and call it "#2"
FONT 1, 2: COLOUR RGB(GREEN)
BOX 15, 15, 265, 35, 2, RGB(red)
text 20, 20, "OUTSIDE READINGS"
font 1:colour RGB(yellow)
Text 15, 110, "Temperature = "
text 180, 110, "Celsius"
Text 40, 130, "Pressure = "
text 180, 130, "HPA"
text 40, 150, "Humidity = "
text 180, 150, "%"
'**************************************************************
'Main program

do
If Loc(#2)<>0 Then ' is there some data in the buffer?

' This is where I am struggling
' To receive data from HC-12 Temp,Press,Humidity



lable
EndIf
Loop
'**************************************************************
sub lable
pause 200
Text 120, 110,TVS$
pause 50
Text 120, 130, PVS$
pause 50
text 130, 150, HVS$
End Sub
'**************************************************************


I have tried with no success maybe some kind person can help me
Regards
John
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:20am 16 Jan 2018
Copy link to clipboard 
Print this post

Tackle it one step at a time.
Start with the device that is getting the readings and print to the console so you can see whats happening.
  Quote   SETTICK 10000, doread ' reading every 10 seconds
OPEN "COM2:4800,64" AS #2 ' open the first serial port with a speed of 4800 baud
bme280_init
SUB doread
myt = bme280_read_temp()
' get the readings
myp = bme280_read_pressure()
myh = bme280_read_humidity()
PRINT STR$(myt,3,1);" ";;STR$(myp,5,1);" ";;STR$(myh,3,1) ' print the readings formatted to make reading easier
PRINT #2, STR$(myt,3,1);" ";;STR$(myp,5,1);" ";;STR$(myh,3,1) ' when you are happy with the results, start sending them to the other device
END SUB


I have used SETTICK to initiate a reading every 10 seconds. This method is better than using a pause. You can vary the reading times without upsetting the frequency of readings.

I have formatted the values into fixed lengths so they will be easier to extract the various parts.

Only after you have something that look right on the console, do you start sending it to the other 'mite and doing any fancy display work.

Jim
VK7JH
MMedit
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 01:03pm 16 Jan 2018
Copy link to clipboard 
Print this post

Hi TassyJim
The TX unit is a MicroMite Explore-28 module and the SETTICK will not work not sure why. Gone back to do loop and every thing is running and printing to console. I can also receive data on the backpack through HC-12 but not in order. Would really like to print data in order if possible.
Regards
John
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 03:35am 17 Jan 2018
Copy link to clipboard 
Print this post

I would be concerned if SETTICK wasn't working but for now, show us the code in the DO/LOOP you are using for sending.
A few sample lines of output from the console too please.

There are many ways to achieve the same thing. and it is difficult to suggest things blind (and confusing for you).

Your current loop on the receiving module will help also.

Jim
VK7JH
MMedit
 
macca
Newbie

Joined: 21/02/2017
Location: Australia
Posts: 32
Posted: 01:37am 18 Jan 2018
Copy link to clipboard 
Print this post

Hi here is the code do loop for tx.

Open "COM2:4800,64" As #2 ' open the first serial port with a speed of 4800 baud
bme280_init

do
pause 10000
'Sub doread
myt = bme280_read_temp() ' get the readings
myp = bme280_read_pressure()
myh = bme280_read_humidity()
Print Str$(myt,3,1);" ";;Str$(myp,5,1);" ";;Str$(myh,3,1) ' print the readings formatted to make reading easier
Print #2, Str$(myt,3,1);" ";;Str$(myp,5,1);" ";;Str$(myh,3,1) ' when you are happy with the results, start sending them to the other device
loop
'End Sub


this is the data received on the console
24.1 974.8 69.7
24.1 974.7 69.1
24.1 974.8 68.7
24.1 974.8 68.5
24.1 974.8 68.4
24.2 974.8 68.3

This is the do loop on the rx side

do
If Loc(#2)<>0 Then ' is there some data in the buffer?
LINE INPUT #2, T$
font 1: colour rgb(yellow)
Text 50, 110,T$
pause 100


endif

Loop

I hope this is okay
Regards
John
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 02:43am 18 Jan 2018
Copy link to clipboard 
Print this post

I have made a small change to the sending routine. I have an extra semicolon in it and have added a "$" to the start of the line. This comes in handy when you are looking for the start of data strings.
I usually have an 'end of data' character as well.

The receiving side simply uses MID$ to divide the string up into the three data values.

  Quote   'sending
DO
PAUSE 10000
'Sub doread
myt = bme280_read_temp() ' get the readings
myp = bme280_read_pressure()
myh = bme280_read_humidity()
PRINT "$";STR$(myt,3,1);" ";STR$(myp,5,1);" ";STR$(myh,3,1) ' print the readings formatted to make reading easier
PRINT #2, "$";STR$(myt,3,1);" ";STR$(myp,5,1);" ";STR$(myh,3,1) ' when you are happy with the results, start sending them to the other device
LOOP

'receiving
DO
IF LOC(#2)<>0 THEN ' is there some data in the buffer?
PAUSE 100 ' wait for the line of data to arrive
LINE INPUT #2, T$
TVS$ =
MID$(t$,2,5)
PVS$ =
MID$(t$,8,7)
HVS$ =
MID$(t$,16,5)
FONT 1: COLOUR RGB(YELLOW)
TEXT 120, 110,TVS$
TEXT 120, 130, PVS$
TEXT 130, 150, HVS$
ENDIF

LOOP


When posting code, try and put it between 'CODE' markers. It makes it easier to read.

Jim
VK7JH
MMedit
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 03:19am 18 Jan 2018
Copy link to clipboard 
Print this post

While the method above will work, it is far from ideal and will come back to bite you in the not to distant future.

You will find that interrupts are your friend. Get to know them.
You need to work out why SETTICK was not working for you. Life is so much easier with it.

On the receive side, serial ports can have interrupts too.
Instead of continually checking to see if there is any data, you set the interrupt to run when you have x bytes in the buffer.
This lets you concentrate on doing other things while you wait. It may not be needed in a simple program but "get to love interrupts" while you are willing to learn.

One big problem with wireless links and serial in general is it is not reliable.
You can miss the start of a data packet, miss the end, or have some of the middle corrupted by interference.
I prefer a 'start' character, fixed length or an 'end' character followed by a simple checksum if the data is critical.

In your program, using LINE INPUT will cause the receiving program to hang if the end of line characters are not received.

There have been plenty of discussions on this forum about various method to 'play safe' with serial links.

Jim

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