Pages

Friday, September 12, 2025

Javascript Speech Synthesises

For an index to all my stories click this text.

I like Javascript. I really do. The language is easy to learn, versatile and extensive. You just make a simple (or complicated) webpage, put some Javascript code in it and it runs on your PC, Raspberry, phone or tablet. Interfacing with the ESP8266, ESP32, your home automation system or a myriad of other devices and services is generally not difficult to achieve.

And there is speech synthesises.......

Have your computer speak to you.

The Javascript commands for having your computer/phone/tablet speak to you are really easy.

var msg = new SpeechSynthesisUtterance();

This starts a new Speechsynthesis instance and we call it msg.

msg.text = "this is my text"

Obviously the text that the message will speak = "this is my text"

speechSynthesis.speak(msg);

And this speaks out the message.

That is really all there is to it.

Now let us look to the next html code with a Javascript example.

<!DOCTYPE html>
<html lang="en-US">
<body>

<h2>Javascript Speech</h2>

<script>

var msg = new SpeechSynthesisUtterance();
msg.text = 'I have put the lamp on';

speechSynthesis.speak(msg);

</script>
</body>
</html>

Copy this code in your favorite text editor (I use notepad) and save it as speech01.html Make sure not to save it as a txt file. So use "Save as" for that. Save the file in a directory of your choice.



As you can see the file was saved as speech01 and seen as a Firefox HTML document. If your default browser is Chrome you should see the file as a Chrome HTML file.

Double-click the file and your browser will open and the words 'I have put the lamp on' will be spoken. Naturally you will have to make sure that your speakers are on and the volume is up. The text shows where this is going.......

Neat huh ???

For the next step I urge you to change your default browser to Chrome or Edge as these browsers have more posibillities for speech synthesises as Firefox has. You can always left-click on the html file and choose open with Chrome or Edge provided these are installed on your computer. You might try with other browsers (I haven't) to see if that works.

Changing the language and voice

Now we know how simple it is to have the computer speak to us we might want to change some parameters. Again: this works in Chrome and Edge but not in Firefox.

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
msg.voice = voices[0];
msg.volume = 1; // From 0 to 1
msg.rate = 1; // From 0.1 to 1
msg.pitch = 1; // From 0 to 2
msg.lang = "en";

These are the parameters you can change.

msg.voice = voices[0];

You can most of the time choose between 0 and 1. This will change the voice sometimes from female to male or between different male/female voices. Choose what sounds best to you.

msg.volume = 1;

Set this to 0 and speechsynthesises is set off. Set this to any value between 0 and 1 (like 0.2) and you can have the voice whisper without having to change the volume settings on your computer.

msg.rate = 1;

This will set the speech rate. from 0.1 which is veeerrrrrryyyyyy ssssssslllllloooooowwwwwww to 1 which is the normal speech rate.

msg.pitch = 1;

This will set the pitch of the voice. 0 is very low and 2 is high. 1 Is the standard value.

msg.lang = "en";

And finally this allows us to choose the language in which the text will be spoken.

msg.text = 'I have put the lamp on';

This one we have seen behore in the first (small) program. And this is where to put the text that has to be spoken.  So if you change msg.lang into another language you need to alter the text in msg.text in the text for that language.

If you want to change the text in Dutch (hey that's my native language) you would need to set the following parameters:

msg.lang = 'nl'
msg.text = 'Ik heb de lamp aangezet'


Another example

Here is another example that would speak out a fake temperature setting. In this example all parameters are available so you can change them to your liking.

<!DOCTYPE html>
<html lang="en-US">
<body>

<h2>Javascript Speech</h2>

<script>

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
msg.voice = voices[1];
msg.volume = 1; // From 0 to 1
msg.rate = 1; // From 0.1 to 1
msg.pitch = 1; // From 0 to 2
msg.lang = "en";

msg.text = 'The temperature is' + 18 + 'degrees';

speechSynthesis.speak(msg);

</script>
</body>
</html>

Just copy this into your editor and save it as speech02.html Go to the directory where you saved it and double-click on it and the webpage will open and speak the text. Alter some settings in the editor, save it again and reload the page.

What languages are available ???


Javascript uses the BCP 47 Language Codes and here is the complete list of languages that are available:

ar-SA Arabic Saudi Arabia
cs-CZ Czech Czech Republic
da-DK Danish Denmark
de-DE German Germany
el-GR Modern Greek Greece
en-AU English Australia
en-GB English United Kingdom
en-IE English Ireland
en-US English United States
en-ZA English South Africa
es-ES Spanish Spain
es-MX Spanish Mexico
fi-FI Finnish Finland
fr-CA French Canada
fr-FR French France
he-IL Hebrew Israel
hi-IN Hindi India
hu-HU Hungarian Hungary
id-ID Indonesian Indonesia
it-IT Italian Italy
ja-JP Japanese Japan
ko-KR Korean Republic of Korea
nl-BE Dutch Belgium
nl-NL Dutch Netherlands
no-NO Norwegian Norway
pl-PL Polish Poland
pt-BR Portuguese Brazil
pt-PT Portuguese Portugal
ro-RO Romanian Romania
ru-RU Russian Russian Federation
sk-SK Slovak Slovakia
sv-SE Swedish Sweden
th-TH Thai Thailand
tr-TR Turkish Turkey
zh-CN Chinese China
zh-HK Chinese Hong Kong
zh-TW Chinese Taiwan


So if you are Belgian or Dutch and like the soft touch of the Belgian voices set:

msg.lang = "nl-BE";
msg.text = 'Ik heb de lamp aangezet';


Fun to play with.

Remember the Javascript pages made to control an ESP8266 and get information from that ESP ??? Next time we are going to incorporate the speech synthesises into that page so you will have an audible feedback on the commands you have send to the ESP and sensor readings from that ESP.

For now you have something funny and usefull to play with.

Till next time
have fun

Luc Volders


Friday, September 5, 2025

Autostarting a program with Raspberry Bookworm OS

For an index to all my stories click this text

October 2018 I wrote a story on how to build an internet radio with the Raspberry Pi Zero. You can find that story here: https://lucstechblog.blogspot.com/2018/10/raspberry-pi-internet-radio-part-3.html

As you might know (as a faithfull follower of this weblog) I am building a second version for using in my living room. The old one is still working in my mancave, and stays there.

The old one uses the, at that time, current Raspberry OS. And of course I am now going to use the latest version. And that posed a small problem.

The previous version (which still works flawlessly) modified the LXDE-pi file in a way that made the internet radio program start automatically when the Pi Zero booted. And that does not work anymore.

For those that are interested I'll show you how to make a Python program autostart with Raspberry Pi's Bookworm OS.

Modify .bashrc

There are several ways to make a program, any program, autostart but this is one of the easiest.

Open the console and type:

sudo nano /home/pi/.bashrc

This opens the .bashrc file in the Nano editor. Please not the . at the beginning of the .bashrc filename. This makes the file normally hidden.

This is a fairly large file. Scroll down to the end of the file, and at put down the next two lines:

echo Running at boot
python /home/pi/radio.py


Then press CTRL-O to save the file and CTRL-X to quit the Nano editor.

You can alter python /home/pi/radio.py in any program you want to start when the Pi boots.

Reset the Pi with:

Sudo reboot now

And the Pi will reboot and automatically runs your program.

That's all for now

Till next time
Have fun

Luc Volders

Friday, August 22, 2025

Dweet.cc with MicroPyton

For an index to all my stories click this text

After my story about Dweet.cc and Freeboard I got some mails from readers of that wanted to know how to send data to Dweet.cc and retrieve data from Dweet.cc with MicroPython.

Well here we go.

Sending a dweet to Dweet.cc


The API call I used to send a temperature value to Dweet.cc with the thingname lucstechblog is as follows:

https://dweet.cc/dweet/for/lucstechblog?temperature=25

To use that API call in a MicroPython program you can use the following code: 

import network
import urequests

# Router credentials
ssid = "YOUR_ROUTER_NAME"
pw = "PASSWORD"
print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

# wifi connected
print("Connected. IP: ",str(wifi.ifconfig()[0], "\n"))

# Replace 'lucstechblog' with your actual thing name
# Replace valuename with the name of the value you are sending
# Replace value with the actual value
thingname = 'lucstechblog'
valuename = 'temperature'
value = 25
value = str(value)

url = 'https://dweet.cc/dweet/for/'
url = url + thingname
url = url + "?"
url = url + valuename
url = url + "="
url = url + value

response = urequests.get(url)
print(response.text)
response.close()



That is it.

Put this code in Thonny and press the "run" button. And you will get the next response in the shell:



Of course your IP address will be different.
The response clearly states that the command had succeeded.

I will break the most important part of the code down here for you.

thingname = 'lucstechblog'
valuename = 'temperature'
value = 25
value = str(value)

These are the variables that need to be send to Dweet.cc

I used lucstechblog for the thing name but please use your own thing name. You can choose any name you want but best practice is to make it relevant.
Please be aware that we are sending a public dweet. So anybody in the world that sends a dweet with the same thing name will alter your value.

Then there is a valuename. I used temperature but use something significant like "kitchen-temperature" or "mancave-temperature". For a single dewwt this looks irrelevant but wait till you build a complete home automation system with this.

And then there is the value itself.
If the value is a number (integer or floating point) like in this example you need to convert it into a string like this example shows.

url = 'https://dweet.cc/dweet/for/'
url = url + thingname
url = url + "?"
url = url + valuename
url = url + "="
url = url + value

This is the code that combines all variables into the api call. Just make sure to incorporate the "?" after the thingname and the "=" after the valuename.

I split the code up like this so you can easily put this in your own program and replace the variable names into your own names.

Retrieving a value from Dweet.cc

The code for retrieving a value from the Dweet.cc server is:

https://dweet.cc/get/latest/dweet/for/my-thing-name

In this example it would be:

https://dweet.cc/get/latest/dweet/for/lucstechblog

Let's translate this in a MicroPython program.

import network
import urequests
import ujson

# Router credentials
ssid = "YOUR_ROUTER_NAME"
pw = "PASSWORD"
print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

# wifi connected
print("Connected. IP: ",str(wifi.ifconfig()[0], "\n"))

# Replace 'my-thing-name' with your actual thing name
thing_name = 'lucstechblog'

url = 'https://dweet.cc/get/latest/dweet/for/'
url = url + thing_name

response = urequests.get(url)
print(response.text)
response.close()

And here is the important part for this program:

url = 'https://dweet.cc/get/latest/dweet/for/'
url = url + thing_name

I splitted the api call in two parts. The first part is the general part and the second part adds your thingname. That is the variable you just created.

And this would gain the following response:




So this proves that it worked.

Decoding the JSON response.

So now we know that this works. However the response is JSON code. And unfortunately that is not direct usable in our program.

Suppose you want to display the temperature on an oled screen, or build a physical thermometer pointer with a servo, or use a bunch of neopixels to display the value like an old-school thermometer.
The JSON code would certainly not be suitable as a value we can work with. We have to decode it.

Here is the complete program that rertrieves the dweet and extracts the value.

import time
import network
import urequests
import ujson

# Router credentials
ssid = "Ziggo2903181"
pw = "ptzbB2ohKbgs7agp"
print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

# wifi connected
print("Connected. IP: ",str(wifi.ifconfig()[0], "\n"))

# Replace 'my-thing-name' with your actual thing name
thing_name = 'lucstechblog'

#url = 'http://192.168.178.62:8000/get/latest/dweet/for/Kit-pow'
#url = 'http://dweet.me:3333/get/latest/yoink/from/Man-temp'

url = 'https://dweet.cc/get/latest/dweet/for/'
url = url + thing_name

response = urequests.get(url)
print(response.text)

print ("============================================")
# Parse the JSON string
data = ujson.loads(response.text)

# Extract the temperature value
tempvalue = data["with"][0]["content"]["temperature"]

# Display the result
print("Temperature is:", tempvalue)

The important parts are these:

data = ujson.loads(response.text)

We create a variable that decodes the JSON response in its individual parts

tempvalue = data["with"][0]["content"]["temperature"]

There we extract the temperature value and put it into the tempvalue variable.

print("Temperature is:", tempvalue)


And this is where we print the actual value in the shell.

If your JSON code looks different you can use a JSON decoder of which there are several on the internet.

Now the value is stored into the tempvalue variable we can use it for our project.

Decoding JSON structures is a bit puzzling.


Click here to buy my book on the Raspberry Pi Pico W

But then you could buy my book on MicroPython with the Raspberry Pi Pico W that explains it in detail and shows how to get help from a JSON decoder.


Till next time
Have fun

Luc Volders



Friday, August 15, 2025

Freeboard with Dweet.cc

For an index to all my stories click this text.

In a previous story I informed you (as if you did not know) that Dweet.io stopeed working. They suddenly ceased their service and left many users in the dark. Their IOT projects just stopped working. You can read that story here:
https://lucstechblog.blogspot.com/2025/08/dweet-is-dead-long-live-dweet.html


Dweet.io was a great free service and what's more there was a good looking free to use dashboard available. It is called Freeboard and I wrote a few stories about this:
- A first look at Freeboard 
- Use Freeboard on Github 
- Run your own Freeboard on a Raspberry Pi

And as Dweet.io is not working anymore would I wondered if it would be possible to use Freeboard with one of the rising alternative services.

Altering the Freeboard source code

As written in the story about Dweet.io shutting down, there is an alternative that uses almost the same API calls. The name is Dweet.cc. The only thing you have to do is to alter dweet.io into dweet.cc in your api calls and your ESP8266, ESP32 or Raspberry Pi Pico's can talk to Dweet.cc.


Freeboard has a special datasource accessible called Dweet.io and of course that does notwork anymore.

So I started with adjusting the Freeboard source code.

In the story Run your own Freeboard on a Raspberry Pi I showed how you can download Freeboard and install it on your own PC or a Raspberry Pi.
Freeboard is written in Javascript and that offers opportunities for altering the code.

So I started opening all the HTML, CSS and JSON files in a text editor. I searched for dweet.io and changed it in dweet.cc
Well that did not work. Hmm.

JSON

And then I realized that there was a Datasource with the name JSON.


So I started by sending a simple api call with my browser to Dweet.cc:

https://dweet.cc/dweet/for/lucstechblog?temperature=25

And that worked. I got this as a result:


Ok, that worked.
For retrieving dweets you need to use:

https://dweet.cc/get/latest/dweet/for/my-thing-name

And in this case I had to replace my-thing-name into lucstechblog.

For more information about this, open the index of this weblog and look for Dweet. There are detailed stories on how to use it.
For testing please use your own "thing" name.

So now I had to implement this in Freeboard.
It really is easy and I am going to show you how to get the value for the thing lucstechblog and the value for temp
erature. Again if you want to try this go ahead but please use your own thing name.

First step is to put the get API call into the JSON configuration menu.

When filled in press "SAVE"


Now choose ADD Pane and a smal window opens.


Press the  + on the top right side of that window


A pop-up window shows in which you can choose what kind of widget you want. In this example choose Gauge.


In the menu fill the data in as shown.
Pressing the datasource test on the right side gives you the opportunity to walk through the JSON steps.
Press SAVE


And there it is, my simple dashboard with only a gauge.

Now you can add multiple widgets to get your own dashboard up and running with Dweet.cc

If you have any questions that you can not find in the stories on this weblog) do not hesitate to send me a mail.

Conclusion.

Getting Freeboard to work with Dweet.CC was easier than I thought.
Just one problem remains...........Dweet.cc is again a cloud service and I wonder how long before THEY cease operation.........

So my main goal is still to build my own Dweet server that I can run locally. And guess what: I already have that running. It runs on a humble Raspberry Pi3 with a USB stick for memory. The base code was written by a friend of me and I enhanced it with a real database and some other stuff.
I am testing it as we speak.

So keep tuned for further updates on building your own Dweet server. But for now can can get it running with Dweet.cc

Till next time.
Have fun !!

Luc Volders

Friday, August 8, 2025

Dweet is dead, long live dweet

For an index to all my stories click this text.

I fall for it every time, and this time I have had enough.
Read on if you want to know what this is about.

It started a few year ago.

First there was Blynk.I was using Blynk for several projects. You could use their free service on which you could use a limited amount of IOT devices. But you could also install your own Blynk server on a Raspberry Pi and then you could use unlimited devices. And suddenly they switched to Blynk 2. The free server was removed from Github and the accompaning App was removed from Android Play.
Blynk 2 had at that time just a very limited free use. So that was the end of it.

Then there was IFTTT. They suddenly stopped allowing users to use free webhooks. You needed a payed subscription for that. So for using IFTTT with your IOT projects you suddenly needed a payed subscription. So that was the end of it.

Appybuilder, which was an app-building system based on MIT's App Inventor ceased working some time ago.

And the list goes on and on. Several services start giving their customers free access and then suddenly become paid services or quit alltogether.

And now Dweet

I have made some projects with dweet.io and published several stories about this service on this weblog. If you have no clue about what Dweet is read this story first:
https://lucstechblog.blogspot.com/2019/05/dweet-volatile-iot-cloud-service.html

And just January this year they quit too.


This was the message they posted on Twitter (X).
And that really pisses me off as there were lots of users.
So all the projects you made with Dweet.io just stopped working.

And what's more: this also shuts Freeboard down.
For those in the dark: Freeboard is a free IOT dashboard that offers buttons, switches, gauges, leds etc, etc. etc. With this you can make your own IOT dashboard for free but....... it relys on Dweet.io

And to be frank I loved Dweet for being free and it's simplicity.

Dweet users to the rescue.

I was not the only one who was pissed for being disappointed for the umpteenth time.

A few clever users came to the rescue and started a free public Dweet server by themselves. But there is a catch.

dweet.cc
This is the best alternative for dweet.io They claim on their website that at the moment of this writing a total of 1127113 dweets have been send.
It is free and uses nearly the same API.
The catch is that you need to change dweet.io into dweet.cc in the API calls.

dweet.me

Another alternative for dweet.io Dweet.me started 15 March 2025 and claim that they already had more than 1 million dweets on April 24 2025.
On the positive side it is just as free as dweet.io was, and it even offers someting extra. Dweet.io saved the last 5 messages. Dweet.me saves the last 8 messages.
On the negative side the website mentiones it is rate limited, although it does not state what the maximum rate is. And the API calls are more deviant from the dweet.io ones.
This means that you need a bit more altering your projects code.

dweetr.io

This is the last alternative I found. At the moment of this writing the number of dweets used was 57. Not a lot really. And there is a catch. You can only have 2 "things" for free. If you need more you will need a pro subscription. On the positive side: the subscriptions are cheap 25USD for 25 things and 49USD for 50 things for a period of 5 year !!!
The dweetr.io API looks similar to the original dweet.io. You need to change dweet.io into dweetr.io in the API call.

The API calls

I am going to show you the basic API call to send a dweet for the original dweet.io and for the 3 alternatives. So you can see for yourself what changes are needed to use the service.

Send dweet with dweet.io
This will not work anymore, but for comparing purpose only.
https://dweet.io/dweet/for/my-thing-name?hello=world

Send a dweet with dweet.cc
https://dweet.cc/dweet/for/my-thing-name?hello=world

Send a dweet with dweet.me
https://dweet.me:3334/publish/yoink/for/my-thing-name?hello=world

Send a dweet with dweetr.io
http://dweetr.io/dweet/for/my-thing-name?hello=world

As you can see the changes are minimal. Nevertheless you need to alter all your original dweet.io projects.

Which one to choose.

Well that is a difficult question.
Both dweet.cc and dweet.me claim to already have processed more than a million dweets. So it looks like their servers are robust. Dweet.me mentions on their website that it is rate limited and I send them a mail about that. Next to that their API is a bit different so dweet.cc looks like the better choice.
The limitation of just 2 "things" for the free tier makes dweetr.io the least attractive choice.

Mail me if you want the sourcecode for micropython or Arduino code for dweet.cc if you do not get this working. And maybe I am going to do a story about this anyhow.

And Freeboard ?

Freeboard will not work with any of these alternatives right out of the box.
I am going to try to get it working again but that might take some time, if I get it to work at all.........

But I had enough !!!

That's what I wrote at the beginning of this story.
And I am really fed up with companies or private individuals that offer IOT services for free and after a while start charging for subscriptions or quit the service all together.

And like you have seen in this story. There are alternatives to Dweet.io and just like the original they are free to use. But how long will it take for the developer to get fed up with it and shuts the service down, or decides it costs too much bandwidth and needs to charge money for the service.

So what is the real alternative.
Well, to put up your own server at home using a cheap Raspberry Pi or a small (obsolete) PC. That is what I am researching now for my future IOT projects. A Raspberry Zero is quite capable running a dweet alike service and will set you back just a few dollar/euro. So that is a serious option.
I'll keep you up to date through this blog, so keep returning here.

Till next time,

Luc Volders

Friday, July 18, 2025

3D Print your own book ornaments

For an index to all my stories click this text.

As you might know I have several hobbies. electronics is one of them and bookbinding another.

For the decoration of a book I needed some ornaments. Bookbinding shops are hard to find. And I did not want to wait for one of the few bookbinding fairs in the Netherlands. So I decided to try to build some myself.

I am not a metalworker or woodworker but I do have a 3D printer. And I set out to make the ornaments with that.

Search ornaments on the web

I started by using Google to search for corner-ornaments. And that turned out well, I found many.



Copy the image with ctrl print-screen and paste it in your favorite
image editor. I use The Gimp for that: https://www.gimp.org/



Cut out the picture you want and save that to your harddisk.



Use convert.io to convert it to SVG



Import the svg into tinkercad and scale it to whish.
Mine was about 4 cm width and depth. I scaled the height to 1mm and then exported the STL.



Next I imported it in my slicer. For simple things like this I use the Creality slicer.

I sliced this at .3 mm.
That meant that it will have 3 layers and prints fast about 10 minutes for 2 pieces



Next step was printing them. I used white PLA as that is the easiest color to paint afterwards.



The printed ornaments were placed on an old newspaper and I sprayed them with gold and silver acrylic paint. I used a spraycan for this and of course did it outside.



And here is the result. I placed them on a book (pen for scale) with an artificial leather cover and they look quiete nice !!! At the time I did not glue them on as I was not yet shure which color would match best.



At closeup you can see the printing artefacts. But you will not notice them from a distance. Next time I'll try the ironingsetting in my slicer. For now this is good enough for me.

Till next time,
have fun


Luc Volders










Friday, July 11, 2025

Getting the right time: another method

For an index to all my stories click this text

Getting the right time is often a requirement for IOT and other projects.
Usually we use an NTP server for this like described in a previous story on this weblog which you can find here: http://lucstechblog.blogspot.com/2023/04/getting-right-time-with-micropython.html

There is just a small problem with this. If you have read that story you will know that you need to make a manual adjustment in the software for the Daylight Savings Time to get the right time. And that is annoying with a finished project. This means that you must update your program twice a year.

What if you want your program to automatically adjust to the right time ??
Well here is how to do that with MicroPython.

The pitfall.

There is no way to automatically get the right time if your finished project is regularly placed in another location, unless you are sure they are in the same timezone.
Your exact time is dependent on your geographic location. The local time in London is different from the time in Amsterdam for example.

So when your project is moved internationally an adjustment must be made for the location where it is at.
There is a trick for getting your location and we are going to use that here. However when the project moves from London to Amsterdam undoubtedly the microcontroller needs to contact another router for wifi access. And to achieve that you need to fill in the routers credentials. And there is your manual involvement.

Getting your location.

For getting the right time your program needs to know your location. And here is a nice trick for getting your location.

Your router is likely connected to a local internet provider. So you will get an internet IP address that is likely to be from your own timezone.
By connecting to the ip-api.com service you will get your internet IP address.

Let's try this first.



Just point your browser to https://ip-api.com/
scroll a bit down and there is your information.

I camouflaged my own IP number as I want some privacy.
But look at the info and you can see that IP-API.COM estimates that my IP number originates from the town Boekel in the Netherlands.

Well actually that is not my location but the important part is that this is in the same Time-Zone as I am. So using my Internet IP number indeed points to the right timezone.

When you move your project to a different location you only have to point your browser to https://ip-api.com/ to know if your program will automatically get the right timezone. If that is so you do not need to make any changes to your program.

We will need the IP address in the next step which is getting the right time. But to achieve that we first need our program to fetch the IP address from the ip-api.com website.

Using the Internet IP address to get the right time

Now let's have a look at the ip-api.com documents page: https://ip-api.com/docs



Above shows the part from the documentaion that tells how to use the api to get the response in JSON code.

http://ip-api.com/json

So this is the only part we need to translate into MicroPython. And here it is.

import network
import urequests

# Router credentials
ssid = "YOUR-ROUTERS-NAME"
pw = "YOUR PASSWORD"

print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

def get_public_ip_address():
    response = urequests.get('http://ip-api.com/json')
    json_data = response.json()
    return json_data['query']

ip_address = get_public_ip_address()

print(ip_address)



Running this program will put the Internet IP-address into the variable ip_address and prints it out in Thonny's shell.

I dont think this needs any explanation. The received data is JSON code and we distill the information from the line "query" from that and that presents us the IP address.



If you need more information on how to program in MicroPython and how to use the requests library or to distill JSON information I can recommend my book: Raspberry Pico W simplified. These things are discussed in details in the book.

You can buy it from Amazon. Click here or the above picture for the link.

Using the IP-Address to get the right time.

Now we have our Internet IP-Address we can use that to get the right time for our time-zone. We are going to use the https://timeapi.io/ service for that.



https://timeapi.io/ is a free service that will provide us the right time for our location. To do so we use their API call and provide our Internet IP-address. You can find all documentation on this site: https://timeapi.io/swagger/index.html



As you can see there are a lot of possibilities. We can use our IP address to get the right time and we can also use our latitude and longitude if they are known. Let's stick to getting the time by using the just found IP address.



The page offers you the possibility to try it out. And if you do you will get an example on how to code the API and the results are displayed further on. We are interested in how the API call should be used and the page shows how it is done:

https://timeapi.io/api/Time/current/ip?ipAddress=237.71.232.203

The provided internet IP=address is just a sample. We will have to replace that with our own IP address.

This is how that is done:

response = urequests.get('https://timeapi.io/api/Time/current/ip?ipAddress='+ip_address)

json_data = response.json()

print("Hour  : "+str(json_data["hour"]))
print("Time :  "+str(json_data["minute"]))


The urequests library calls the API and in the call we added our own just found IP-address.



And here is the information shown in Thonny's shell. And believe me the time was accurate.

The complete code.

For your convenience I hereby give you the complete program

import network
import urequests

# Router credentials
ssid = "YOUR-ROUTERS-NAME"
pw = "YOUR-PASSWORD"

print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

def get_public_ip_address():
    response = urequests.get('http://ip-api.com/json')
    json_data = response.json()
    return json_data['query']

ip_address = get_public_ip_address()

print(ip_address)

response = urequests.get('https://timeapi.io/api/Time/current/ip?ipAddress='+ip_address)

json_data = response.json()

print("Hour  : "+str(json_data["hour"]))
print("Time :  "+str(json_data["minute"]))


Power Failure

I am sure you will notice that this is a great way to get the accurate time for your IOT and other projects. Get the significant part of this program and use it in your own project so you will automatically get the right time even after a power failure.

Till next time
Have fun

Luc Volders








Friday, July 4, 2025

MicroPython bytecode speed test

For an index to all my stories click this text

In the previous story I wrote how you can make your MicroPython sourcecode unreadable for most users. I did that for trying to protect my program. The way to do this is to convert your program into bytecode. You can read that story here: 
https://lucstechblog.blogspot.com/2025/06/protect-your-micropython-sourcecode.html

After I published that story here on my weblog I received a mail from a reader that asked if the bytecode was actually faster as standard MicroPython. The question is valid as bytecode is actually easier to interpret as MicroPython code.

So I did some tests.

Prime numbers

I took a smal program that calculated and printed a few thousand prime numbers. Here is the code.

import time

start_time = time.ticks_ms()

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

count = 0
n = 2
while count < 5000:
    if is_prime(n):
        print(n)
        count += 1
    n += 1

end_time = time.ticks_ms()
elapsed_time = time.ticks_diff(end_time, start_time)

print("Elapsed time:", elapsed_time, "milliseconds")


This code took 32993 miliseconds to run on an ESP8266 with MicroPython V1.20.1.

Then I converted the program to bytecode and it took 32149 microseconds to run. So it was 844 miliseconds (almost a full second) faster.

That is 2.5% faster.

So it is a bit faster but not a lot to gain..

Without print

A lot of time is consumed by the print statement. Print is dependend on the serial communication between the microcontroller and your computer. So let's see what we gain if we leave the print command out.

import time

start_time = time.ticks_ms()

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

count = 0
n = 2
while count < 5000:
    if is_prime(n):
        count += 1
    n += 1

end_time = time.ticks_ms()
elapsed_time = time.ticks_diff(end_time, start_time)

print("Elapsed time:", elapsed_time, "milliseconds")


It's the same program without the print command in the while loop.

The program now took 32385 miliseconds to run.

Again I converted it to bytecode and then it needed 31570 miliseconds to run.
That is 815 miliseconds faster. Again almost a second faster.

And that makes it also 2.5% faster.

This is just a small test but this already shows that bytecode is a bit faster as MicroPython code. So you might gain some speed in certain projects.

Conclusion

Byte code is not real native machine language but an in-between step. This small test already shows that bytecode is a bit faster as MicroPython code. So you might gain some speed in certain projects.

This is not a scientific test just a small test to see if there is any speed to gain. Your results might vary depending on the Microcontroller you are using (ESP8266, ESP32, Raspberry Pi pico etc.) size of the program, libraries used and commands used. So make some tests for yourself.

Till next time,
have fun


Luc Volders