开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

HABalloon Project


 

Truly?open source?High Altitude Balloon tracking using Arduino and SI5351 to transmit WSPR, JT9 and/or JT65 telemetry reports. Free for non-commercial use, so long as you keep modifications and derivatives of this code open source.?
?
There are existing projects out there on the web, but none from what I could find were open source. One of the more common options is the U3S or a modified variant of that particular firmware. This firmware is in it’s own class. I am not a programmer, so the code may not be perfect, but it works. Suggestions for improvements of the code are welcomed if you have the skillset.?
?
Hardware Requirements:
- Arduino?
- GPS module (U-Blox 6,7, 8 or other high altitude capable device)?
- SI5352 module
- battery and solar system to suit your needs
- antenna (a simple 5 meter per leg dipole, supported with fishing line)
?
Features:
- sync system time to GPS time
- dynamic QTH locator
- dynamic telemetry including altitude, speed, temperature and battery voltage
- transmission modes can include a combination of JT9, JT65 or WSPR
- frequency coverage includes that covered by the SI5351 module
- temperature is calculated from the internal thermistor of the Atmega chip on the Arduino
?
Overview:?
1) GPS is queried for time and system time is set with the function “setGPStime()”, if time is? already set, this is ignored with the? “timeStatus()” check
At this point the GPS is placed into airborne mode (Ublox only)
2) Timing script is called, this script os only run if time has been set, which is critical WSPR, JT9 and JT65 to work.
Depending on the timing needed, this can be configured to different intervals, modes and frequencies.
Once a timing interval is triggered, a message type is generated by calling “genMessageX()” which in itself will call other? functions to generate telemetry data and place it into the “message” string. The message string is then encoded for the specific mode type? and transmitted with the SI5351 module
* GPS is essential for all functions, timing, locator, altitude, speed, only voltage and temperature are independent, however without? proper GPS timing, none of the above matters.
?
Flashing to your Arduino:
Make sure you change your configurations and flash to your Arduino prior to connecting the Arduino to the GPS module.
?
Hardware connections:
GPS connects to the Arduino “hard” serial ie “tx” and “rx” pins, don’t try to use soft-serial its very buggy for such a large program as this with so much going on.
The SI5351 connects to A4 and A5 of the Arduino which are the I2C pins.?
Battery voltage monitor connects to pin A7


 

Standard telemetry format as it is coded in v0.3 is as follows, transmission on x minutes and x frequency:

WSPR - 00:02 -?14.097150 MHz - CALL, 4-digit locator, altitude (dbm format below)
FT9 - 00:05 -?14.097250 MHz - CALL, 6-digit locator
FT9 - 00:06 -?14.097250 MHz - CALL, altitude, voltage, speed, temperature (format below)
WSPR - 00:32 -?10.140250 MHz - CALL, 4-digit locator, altitude (dbm format below)
FT9 - 00:35 -?10.140350 MHz - CALL, 6-digit locator
FT9 - 00:36 -?10.140350 MHz - CALL, altitude, voltage, speed, temperature?(format below)
FT9 - 00:59 -?14.097250 MHz - CALL, Beacon message (HAB-01)

A typical WSPR message would be "NOCALL FN35 30" which decodes to: NOCALL FN35 at altitude of 8000 to 9000 Meters
A example JT9 message using format?CALL, altitude, voltage, speed, temperature would be "NOCALL KMDM" which decodes to: NOCALL, 9000-10000 Meters altitude, ?battery voltage?4.11 - 4.2 Volts, speed?15 - 19.9 Knots, temperature?-20 - -23.9 C

"dbm" altitude format - altitude anchored into the dbm field of the WSPR message.
0 = 0 Meters?
3 = 0 - 1000 Meters?
7 = 1000-2000 Meters?
10 = 2000-3000 Meters?
13?= 3000-4000 Meters?
17?= 4000-5000 Meters?
20?= 5000-6000 Meters?
23?= 6000-7000 Meters?
27?= 7000-8000 Meters?
30?= 8000-9000 Meters?
33?= 9000-10000 Meters?
37?= 10000-11000 Meters?
40?= 11000-12000 Meters?
43?= 12000-13000 Meters?
47?= 13000-14000 Meters?
50?= 14000-15000 Meters?
53?= 15000-16000 Meters?
57?= 16000-17000 Meters?
60?= 18000 + Meters?

"standard" altitude (used with JT9 and JT65 modes)
A = 0 Meters?
B = 0 - 1000 Meters?
C = 1000-2000 Meters?
D = 2000-3000 Meters?
E = 3000-4000 Meters?
F?= 4000-5000 Meters?
G?= 5000-6000 Meters?
H?= 6000-7000 Meters?
I?= 7000-8000 Meters?
J?= 8000-9000 Meters?
K?= 9000-10000 Meters?
L?= 10000-11000 Meters?
M?= 11000-12000 Meters?
N?= 12000-13000 Meters?
O?= 13000-14000 Meters?
P?= 14000-15000 Meters?
Q?= 15000-16000 Meters?
R?= 16000-17000 Meters?
S?= 18000 + Meters?

"Voltage" value
A = < 3 Volts?
B = 3.01 - 3.1 Volts
C = 3.11 - 3.2 Volts?
D = 3.21 - 3.3 Volts
E = 3.31 - 3.4 Volts?
F = 3.41 - 3.5 Volts
G = 3.51 - 3.6 Volts
H = 3.61 - 3.7 Volts?
I = 3.71 - 3.8 Volts
J = 3.81 - 3.9 Volts
K = 3.91 - 4 Volts ?
L ?= 4.01 - 4.1 Volts
M = 4.11 - 4.2 Volts
N = 4.21 - 4.3 Volts
O = 4.31 - 4.4 Volts
P = 4.41 - 4.5 Volts
Q = 4.51 - 4.6 Volts
R = 4.61 - 4.7 Volts
S = 4.71 - 4.8 Volts?
T = 4.81 - 4.9 Volts
U = 4.91 - 5 Volts?

"Speed" values in knots
U = 100 + Knots
T = ?95-99.9 Knots?
S = 90-94.9 Knots ??
R = ?85-89.9 Knots
Q = 80-84.9 Knots?
P = 75-79.9 Knots?
O = 70 - 74.9 Knots
N = 65 - 69.9 Knots?
M = 60 - 64.0 Knots
L = 55 - 59.9 Knots?
K = 50 - 54.9 Knots
J = 45 - 49.9 Knots?
I = 40 - 44.9 Knots ?
H = 35 - 39.9 Knots?
G = 30 - 34.9 Knots??
F = 25 - 29.9 Knots?
E = 20 - 24.9 Knots?
D = 15 - 19.9 Knots
C = 10 - 14.9 Knots
B = 5 - 9.9 Knots?
A = 0 - 4.9 Knots

"Temperature" value - Celsius
S = < -44 C?
R = -40 - -43.9 C
Q = -36 - -39.9 C
P = -32 - -35.9 C
O = -28 - -31.9 C
N = -24 - -27.9 C
M = -20 - -23.9 C
L = -16 - - 19.1 C?
K = -12 - -15.9 C
J = -8 - -11.9 C?
I = -4 - -7.9 C
H = 4 - 7.9 C
G = 8 - 11.9 C
F = 12 - 15.9 C
E 16 - 19.9 C
D = 20 - 23.9 C?
C = 24 - 27.9 C
B = 28 - 31.9 C
A = > 32 C


 

Typo in the Hardware requirements :?- SI5352 module. It should be 5351.


 

Yes, that is correct. If course others could be used, but the code would have to be adapted accordingly.?


 

Steve,

I am not a programmer by career, mostly a hardware guy, but I got it working plus encoding the special WSPR telemetry format that the guys from the floater community are using.?

Now, have you done any GPS testing? How the library behaves when the GPS fix has aged and it is not valid anymore? Did you flew it??

Eduard


 

Eduard,

That's good?to hear. I didn't have the script deal with GPS aging, with the cold temperatures at altitude you may see some variation in the internal timing of the Arduino after it is set. It's possible to have the script read the GPS on a schedule to update the internal clock after it's been set. I haven't done any testing to see how long or by how much the Arduino clock is affected by cold temperatures. It would be easy enough to update the code to do this though.

After I got the code working, I built a prototype with LiPo batteries and did ground testing. The script was doing what is was supposed to with those tests, but I never got around to launching a balloon. I wanted to build a proper system with solar charging and build a compact PCB to mount everything on, but never got around to doing?it. I have been busy with other aspects of life at the moment. I would be interested in hearing anyone's stories of success though.

Good luck.

Stephen

On Mon, Mar 18, 2019, 1:18 AM <yo9ict@...> wrote:
Steve,

I am not a programmer by career, mostly a hardware guy, but I got it working plus encoding the special WSPR telemetry format that the guys from the floater community are using.?

Now, have you done any GPS testing? How the library behaves when the GPS fix has aged and it is not valid anymore? Did you flew it??

Eduard


 

Steve,

I am working on implementing the GPS reset routine. Basically, if the fix is lost for some amount of time/number of queries, the GPS goes into reset.

Have you used the isUpdated() and age() methods from the GPS library?

Quoting from the library documentation :?

Validity, Update status, and Age

You can examine an object’s value at any time, but unless TinyGPS++ has recently been fed from the GPS, it should not be considered valid and up-to-date. The?isValid()?method will tell you whether the object contains any valid data and is safe to query.

Similarly,?isUpdated()?indicates whether the object’s value has been updated (not necessarily?changed) since the last time you queried it.

Lastly, if you want to know how stale an object’s data is, call its?age()?method, which returns the number of milliseconds since its last update. If this returns a value greater than 1500 or so, it may be a sign of a problem like a lost fix.




Looks like the isValid() method is set true only once after the first fix and then stays true forever.

age() might be the best candidate.

What do you think?

Eduard
YO3ICT


 

开云体育

You can try, the code as I had originally submitted was large for the tiny 328 memory and might be prone to memory errors if too much is asked of it. The code should be streamlined more to improve performance and reduce the potential for error from overloading the memory . I haven’t tried to implement any GPS validity into the code though. It is a valid point you have though, since the WSPR and JT modes as so dependent upon accurate timing. This code was very early in testing, it worked on the bench but needs to be tested much more.?

On Apr 8, 2019, at 12:32 PM, yo9ict@... wrote:

Steve,

I am working on implementing the GPS reset routine. Basically, if the fix is lost for some amount of time/number of queries, the GPS goes into reset.

Have you used the isUpdated() and age() methods from the GPS library?

Quoting from the library documentation :?

Validity, Update status, and Age

You can examine an object’s value at any time, but unless TinyGPS++ has recently been fed from the GPS, it should not be considered valid and up-to-date. The?isValid()?method will tell you whether the object contains any valid data and is safe to query.

Similarly,?isUpdated()?indicates whether the object’s value has been updated (not necessarily?changed) since the last time you queried it.

Lastly, if you want to know how stale an object’s data is, call its?age()?method, which returns the number of milliseconds since its last update. If this returns a value greater than 1500 or so, it may be a sign of a problem like a lost fix.




Looks like the isValid() method is set true only once after the first fix and then stays true forever.

age() might be the best candidate.

What do you think?

Eduard
YO3ICT


 

Hi,

any update on code HABalloon v3 ??
I tried and works great but after 4hours DT=+5.9seconds on fixed location?
Is there possibility to add simple function to
set again gps time to correct seconds ?


 

Try adding another?setGPStime(); call within the TXtiming() function.

Let me know if this cures the issue.


 

Hi,

thanks for suggestion? I try to put it at the end of timing

? ? ? ? if ((minute() == 2) && (second() <= 30)) ? ?// Tx on minute 2 and 32, "30 second" prevents double transmission. WSPR is 2 minute TX period.
? ? ? ? ? ? {
? ? ? ? ? ? ? loc4calc(); // update 4-digit locator before transmission
? ? ? ? ? ? ? intGPSalt(); // update altitude before transmission
? ? ? ? ? ? ? freq = WSPR_FREQ1;
? ? ? ? ? ? ? setModeWSPR(); // set WSPR mode
? ? ? ? ? ? ? encode(); // begin radio transmission
? ? ? ? ? ? ? delay(50); //delay to avoid extra triggers

? ? ? ? ? ? ? setGPStime();
? ? ? ? ? ? }

I hope this will works better
Anyone improved this code or use it on balloon yet??
For telemetry is this a standard protocol or need something?better to properly decode on habhub?




On Sat, Sep 7, 2019 at 5:22 PM <yo9ict@...> wrote:
Try adding another?setGPStime(); call within the TXtiming() function.

Let me know if this cures the issue.


 

I've improved and enhanced it to also comply with U3B telemetry format.

Its been flown three times. Last flight is still up, more than 44 days airborne and yesterday completed the 2nd lap of the Earth.



The code has some structural resembles to the original HABalloon code, so I've been wanting to try to commercialize it but this dream is slowly fading away.

I will try to put together an archive with everything needed : instructions, firmware, PCB.?


 

Uaau ... 44days it seems you made a big job.
If not a secret if you can put it together will be nice

On Sat, Sep 7, 2019 at 5:44 PM <yo9ict@...> wrote:
I've improved and enhanced it to also comply with U3B telemetry format.

Its been flown three times. Last flight is still up, more than 44 days airborne and yesterday completed the 2nd lap of the Earth.



The code has some structural resembles to the original HABalloon code, so I've been wanting to try to commercialize it but this dream is slowly fading away.

I will try to put together an archive with everything needed : instructions, firmware, PCB.?


 

I read the whole page about ICT3 and I see at the whole code with telemetry protocol you get it to atmega328p excellent.
and the HW is bullet proff for temperature environments ::)
You make me my day if I should see your code?



On Sat, Sep 7, 2019 at 5:58 PM JanV via Groups.Io <jan.vadilijev=[email protected]> wrote:
Uaau ... 44days it seems you made a big job.
If not a secret if you can put it together will be nice

On Sat, Sep 7, 2019 at 5:44 PM <yo9ict@...> wrote:
I've improved and enhanced it to also comply with U3B telemetry format.

Its been flown three times. Last flight is still up, more than 44 days airborne and yesterday completed the 2nd lap of the Earth.



The code has some structural resembles to the original HABalloon code, so I've been wanting to try to commercialize it but this dream is slowly fading away.

I will try to put together an archive with everything needed : instructions, firmware, PCB.?


 

What page did you read?

Have a little more patience, I am putting together the instructions.


 




On Mon, Sep 9, 2019 at 11:22 AM <yo9ict@...> wrote:
What page did you read?

Have a little more patience, I am putting together the instructions.


 

Final instructions, including Firmware and PCB layout, for the ICT-series balloons.


 

fine. thanks? yo9ict.
Question? will work with normal Arduino mini 8MHZ? 3.3V or the timers are only for 4mhz?



On Wed, Sep 11, 2019 at 5:40 PM <yo9ict@...> wrote:
Final instructions, including Firmware and PCB layout, for the ICT-series balloons.


 

Should work but not tested. You should change the fuse bits and the board definition.

Anyway, Arduino Mini has some weight. You'll have very slim chances at circumnavigation.

Stick with the project as it is presented. It works. Do not give more than 3.6V. Stick with the Taitien TCXO, it works exceptionally well. You can fit another type of resonator for the AVR.

Eduard YO3ICT ex. YO9ICT


 

Hi,

I'm testing here WSPR transmitter confused here if I select WSPR? frequency 14095600UL I found signal on
WSJTX 400Hz. So if I want to decode in WSJT-x (1400-1600Hz) then I need to set to 14.094.60MHz on radio.
If I'm right then I need to change the frequency 1kHz up? or I'm doing something wrong?

BR Jan