Saturday, May 9, 2026

Delft Maker fair 2026

 For an index to all my stories click this text

Yesterday 8 may 2026 was the day of the Delft Maker fair.

At the university campus of the Technical University Delft there was a gathering of makers, students, creative minds and loads of visitors.
There were workshops, loads of demonstrations and some novelties.


A 2 meter high contraption with moving eyes, wings and all sorts of other moving parts with a working bubble blowing machine. It was moving around on wheels remote controlled by its maker.


Someone was making lamps from all kinds of vintage products like phones, photocams etc.


A life size build based on the "Theo Jansen "strandbeest". This version did not move on the wind like the original strandbeest but had large motors inside. You could sit on it and move it around with some controls.


3D printing everywhere. And the new hype is of course color printing.


And here is the first one I saw live: the Creality I7 Sparkx
Creality's answer to Bambu. A 4 color 3D printer priced (at this moment) for around 350 USD/Euro. I saw it working and I saw the quality: I want one !!!!!


And a lot of tinkering. Like this antique Singer sewing machine with a motor that drove the sewing part and X and Y Axis that moved the cloth. So you can use it as an embroidery machine. Arduino powered.

There were over 100 stands. There was a hydrogen racing car, a hyperloop, fablabs, cnc machines, laser engravers, workshops, demonstrations and loads more. And of course everywhere Arduino's, ESP32's, Raspberry Pi's and Pico's. Most part of it was outside and the weather was fantastic.

One thing I can not show you here but was really fun was an industrial coffee machine that was insulting everyone who tried to use it.

If you ever have the time to visit a MakerFair I urge you to do so. It gives your creative energy an enormous boost.

Till next time
have fun

Luc Volders

Friday, May 1, 2026

Notifications with NTFY

For an index to all my stories click this text.

When working with IOT projects several things can happen. A certain temperature is reached, movement is detected, a light is set on in a room, someone is at the door etc. etc.etc. When something like this happens you will want to get a notification. You can, of course, build a website on which values are shown. But that implies that you need to go to that website to look at the values.

It is more efficient when you get a notification (an alarm) on your smart phone.



A notification like this is put on the startscreen of your phone so it will always draw your attention.

There is a free service that you can use to get these notifications it is called NTFY
You can find the website here: https://ntfy.sh/

NTFY

NTFY is of course short for NoTiFY. It is a free service that you can use. 

There is a limit of 250 notifications per day for a free or anonymous account. That is 10 messages per hour !!!

If you need more than 250 messages per day then you need to get a paid subscription.

To use NTFY you need to download a (free) app on your phone or tablet. But there is also a desktop (PC) version that can receive messages but can also send messages.

To send notification messages to your phone, tablet or PC there is a simple to use API that can be used with Arduino (C++) and MicroPython.

For using the free version you do not have to log-in or make an account. You can just use it. That is a bit like dweet.

Another similarity to Dweet is that a message/notification consists of two parts: a topic and the message itself. To get the notifications on your Phone or PC you need to "subscribe" to that topic.
A topic might be for example "Alarm" and the message can be "The garage door is open". Another topic might be "Myhome" and a message could be "The temperature = 22 degrees"

You may create as many topics as you like as long as you do not exceed the limit of 250 messages. A topic is created automatic when you send a message with your microcontroller that includes a non existant topic.

And yet another similarity to Dweet is that (unless you have a paid account) the topics are public. This means that anybody can get your messages and notifications as long as they know the topic you are using.
So use a cryptic topicname like LV23kit where LV are my initials, 23 is the year (2023) and kit means that the messages concern my kitchen. Just be creative.

If you need private topics you will need to get a paid plan.

The big difference with Dweet is that NTFY can send notifications to your phone/tablet/pc. Dweet can not send them, you need to collect them yourself. So for sending alarms NTFY is the best option.

There is one extra option that might prove usefull. NTFY can also send emails. So you can get your messages in your mailbox. For alarms that is not really an option as you want an instant notification if something is wrong. However it might be usefull for some of you so I will show how to use this option. With the free version you can send 5 emails per day.

One more thing though. The messages/notifications are stored for 12 hours. After 12 hours the messages disappear.

NTFY on the PC

First thing we are going to do is to get NTFY on your PC. Well that is easy. Just point your browser to https://ntfy.sh/app and you're done.



This is how the webpage looks..



Click on + Subscribe to topic and a window opens that allows you to enter the name of a topic.
Like stated before, for an anonymous (and free account), topics are public so choose a topic name that others can not guess easily.



You can also click on GENERATE NAME and NTFY will generate a topic for you that closely resembles a password.
This will give you some better privacy and secrecy but is more difficult to use on multiple devices at the same time. If, for example, you are using NTFY at the same time on your PC and on your smart phone you will need to find a way to send this cryptic topic name to your phone.

I choose a topic name myself: lucstechblog

Then click SUBSCRIBE.



This is how your screen will look now. On the left there is a list of subscribed topics. At this moment there is just one: lucstechblog. In the center there is a message that no notifications have been send or received with this topic.

NTFY on the Android Phone

To get notifications we need to install the NFTY app from the playstore. You can find it here:
https://play.google.com/store/apps/details?id=io.heckel.ntfy
Or just search for NTFY in the app store.



Install the app and open it.





It looks almost the same as the PC version. 





Press the + at the bottom of the screen for subscribing to a topic. We will use the same topic: lucstechblog
A big difference from the PC version is that there is no option to have NTFY generate a topic for you. This is because the phone version is only used for receiving notifications.

We now have 1 subscription to a topic.

Sending a message from the PC

Click with your mouse on the subscribed topic (lucstechblog)



And at the bottom type a test message like I did. Then click on the small arrow next to the message.



The PC screen will inform you that the message is send.



And you will almost immediately get a notification on your phone.
This is the important part. This shows that we can get alarm messages and other important messages as a notification on our phone.



And the NFTY app will inform you that a notification has been received.
And shows message also in the app.

First steps done.

The first setup is done.

Make yourself comfortable with the concept and create some topics for yourself and play around a bit.

Next time we are going to send notifications from the ESP32 using Arduino language (C++) and from the Raspberry Pi Pico with MicroPython.

A few small tips

You can use the browser version next to the app on your Phone. Just point your browser to: https://ntfy.sh/app That way you can also send messages from the phone that will be received by the PC. You will not get notification alarms through the browser but you will still get them through the app.

You can use NTFY on multiple phones and tablets. As long as they all subscribe to the same topics, they will all get the same notifications/messages.

And please remember that you can make as many topics as you like but there is a limit of 250 messages per day for the free account. The messages are stored on the server for 12 hours after which they vanish.

Although you can create loads of topics it is better and easier to maintain if you just use a few topics and make the messages in the topics more verbal.

Next story covers how to send notifications from your ESP32 with Arduino language (C++) or Raspberry Pi Pico W with MicroPython


So Till next time
have fun


Luc Volders











Friday, April 24, 2026

My rant against some cloud services

 For an index to all my stories click this text

I present you some short stories about web/iot services that changed their free tiers to a subscription model, or quit alltogether. The list will expand when I run into new services that leave their users in the cold.

If you do not want to read all these stories just scroll down to the bottom of this story to read what my point is.

Blynk

Blynk consisted of a cloud based server, an app for your phone and real good solid software for microcontrollers.
First step was to create an account, then write some software for your microcontroller. The last step was to create a nice graphical setup in the app. All was super simple to use and free. And the app really looked fabulous. The access to the cloud server was limited to a few microcontrollers or actions (like setting a button, gauge etc) per user. But you could download the cloud server and install it on a Raspberry. Then you would have unlimited capacitity for free. Then they developed a new version called Blynk 2.0 And then the misery started. First they pulled the plug from the cloud servers. And later on they removed the app from the Play store. So anybody using this service could not expand or re-install it when you switch phones.
Blynk 2 had a really limited free tier although it is better now. But hey you had to reinstall all software on your devices and microcontrollers.


Whatabot

Whatabot is a service that let's you send messages from your Microcontroller (ESP8266, ESP32 Raspberry Pi PicoW etc) to Whatsapp. This is a great way to get notifications on your phone when for example a door opens or lights go on.
To make use of this service you need to add the telephone number of Whatabot to your contacts. And after sending a message to that contact you'll get an API key.
I used Whatabot about 2 year ago and then forgot about it. And a few weeks ago I wanted to use the service again. But I could not get it working. Then I realized that they had changed their telephone number. And by changing the number Whatsapp was not able to receive messages from the service.
Not a big deal, but just a bit annoying as I had to adjust the programs for my microcontrollers


Dweet.io

I have used Dweet.io for several of my projects and wrote stories about it. Dweet.io was a great free service that allowed a microcontroller, a Raspberry, a PC, tablet or phone sending small messages to it and any of the mentioned apparatus to retrieve the message. It worked like an intermediary. One ESP sends the temperature to Dweet.io and another one retrieves the value and depending on it set's a fan on etc.
And suddenly without warning they stopped in January 2025. No reason, no explanation whatsoever. They just pulled the plug, leaving loads of people whose projects depended on them in the dark.
Oh yes, alternatives emerged: Dweet.cc, Dweet.me and Dweetr.io This shows how popular Dweet.io was. However these are maintained by enthousiastic volunteers and who knows when the load gets to big (or to low for their liking) and they cease operation or start charging for their service. And you will have, of course, to re-program all your devices that use this service.


IFTTT

Hey IFTTT still exists !!
Yes but they had a great service called webhooks. And it was free. Using the webhooks you could, for example, give a command to Google Home and that would trigger an ESP to set a lamp on or set the temperature higher, or start a fan etc. etc. etc. I wrote several stories on this.
The service is still available but it will set you back $2.99 a month while it was free for may years. So people using this to trigger devices with Google Home suddenly have to pay for it. And for $2.99 you can only use 20 apps.


IoTtweet

IoTtweet offered a web based dashboard for IOT purposes. There were buttons, gauges, sliders etc. A Microcontroller could send values to the dashboard which then could be shown in a nice graphical environment. Other microcontrollers could retrieve those values and act on them. I wrote a few stories on IoItweet. It was really easy to use.
And suddenly without a warning they pulled the plug.
Anybody who build projects around this was left in the dark.


Servces that stopped but did not effect me


Insteon

In 2022 Insteon went belly-up. It was a complete home automation infrastructure, There were buttons, dimmers, wall outlets, sensors etc. They all communicated with a cloud based server. When Insteon went bankrupt the plug was pulled and all services ceased to work. Your home was left in the dark when you pressed the buttons.....
A few months later Insteon was saved by investors but the shock is still there.....


Logitech Pop buttons

Users of the Logitech Pop buttons got an email from Logitech that they would pull the plug on this service on October 15 2025. That is 8 year after their introduction. And from that on your USD40 to USD90 investment could be used as landfill.


What's my point.

Well obvious I am disappointed by some of these services and at some I am just really mad. So I urge you to be carefull to base your complete project or home automation on a cloud service.

So is there a solution ?

Yes there is for some cases.
The solution is to write your own software and build your own server that replicates these services. Host the server in your own home and the only worry will be a power outage. Cause even when the internet melts down things would still keep working in your own network.

And This is exactly what I am doing.
I am building my own Dweet server (programmed in PHP with an SQLite database) and running it on a Raspberry Pi4 with 2GB memory.
Next to that I am building my own IOT Dashboard with buttons, gauges, switches, sliders all fully customizable. 
This is a long term project and I still have to make integrations of 433Mhz switches and Philips Hue lamps.
But the basic functions work and it is really a fun project.
So stay tuned I might, yes might, publish the complete setup in the future.

Till next time
Have fun

Luc Volders

Friday, April 17, 2026

Using a VPN with Raspberry Pi

For an index to all my stories click this text.

In a previous story I explained what a VPN is and how to install that service when your computer runs Kubuntu (Linux)

This story explains what a VPN is and how to install it on Your Raspberry Pi.
The VPN I am going to discuss here is a different one from the previous story. However this one runs on Raspberry Pi as well on a PC with Kubuntu.

What is a VPN

For those that have no idea what a VPN is and why you could use one I'll give a brief explanation.

Normally when you visit a website with your browser you have a direct connection to that website.

A VPN is a bridge in between. So you send the request for the website to the server of the VPN provider. The connection between your browser and the VPN server is encrypted and their server is a secure server. The VPN then contacts the website, gets the information and sends it encrypted back to you.
That way you do not have direct contact with the website you want to visit. This keeps you safe in countries where free speech is at stake. But it also makes it impossible for the website you are visiting to track you down.

Another advantage is that you can access sites that are geo-restricted. This means that the website you are contacting believes that you are in a different country then where you really are.
For a long time this was popular by people in Europe that wanted to watch certain US restricted TV-shows. Without a VPN the US media server saw that you were in Europe and blocked viewing. If you contacted these media through a VPN you could trick them in thinking you were in the US.

A VPN is secure for both UDP and TCP communication. Therefore you can also mask your IOT communication this way.

Free or paid VPN's

There are free and paid VPN services.
The restriction of a free VPN service is that you have less VPN servers to chose from, the service might not always be available and it may be slower.

I have been using the free VPN service from RiseUp for a while, on my Raspberry, and they were always available and I did not notice any significant speed limitations. RiseUp has no paid services and runs on donations. So if you need to use their serices on a frequent base consider making a donation. That can be done at their webpage: 

https://riseup.net/en/vpn

RiseUp has a no-log policy. That means that they do not keep a log of your activities. That is an extra safety measure that makes sure that no one can see what sites or services you have been using.

Next to the VPN service they also supply a safe email service, and an email-list service.

Install RiseUp VPN

To use a VPN you'll need to install a small software package. This package intercepts all your network communication and sends it to the VPN server.

Installing the RiseUp VPN software on your Raspberry is easy.


Just open Discover from your Application Launcher and search for VPN.

This may look awkward to (maybe) most of you. But I am using the KDE desktop on my Raspberry Pi with Trixie as it is far more convenient then the Raspberry Desktop. And it is fully compatible. 

I really urge you to install the KDE desktop on your Raspberry PI as it is so much better as the Raspberry standard desktop. Installing is easy. You can read my story where I explain the installation here: 
https://lucstechblog.blogspot.com/2025/10/raspberry-trixie-with-kde-plasma.html


Click Install and you're done.
No need to make an account or fill in your email address. Just click and install.

Using the RiseUp VPN


After downloading and installing RiseUp VPN you will find the software in the internet section of the Application Launcher.


Starting the program opens a window that immediately shows that it already has made a secured connection.
The bottom of the window shows to what server you are connected. In this example you can see I was connected to a server in Amsterdam.


If you click on that connection name you'll get a list of available servers. You can chose another server from the list if that makes you more comfortable.

Next to the server there is a small graph that shows if the server is available. A green graph (like in this example) shows that the server is available.

Click on the server of your choice. Then click on the left arrow at the top of the screen. This brings you back to the start-screen.


Click on the Turn ON button ad a new connection is made.
Be aware that switching from VPN server to another server might take some time.


After a short while you will see that the new connection has been made.

That is all.

You can now open your browser and visit any website you want without anybody being able to trace your internet tracks.

Connection status.


At the bottom of your desktop on the right side there are some icons. Like said before: this is the Raspberry Pi running the KDE desktop.
This example shows a small green shield which means that your VPN connection is up and running.

This shield can have several colours.


Well this explains all.

Does it work.

Here is a quick and simple test to see if the VPN works.

Start with disconnecting the VPN server in the RiseUp VPN software by simply pressing the Turn Off button.
Then open your internet browser and visit the following site:

https://www.whatsmyip.org/


The website shows your normal IP address.

Now activate the RiseUp server and choose any server anywhere in the world to your liking. Then again visit https://www.whatsmyip.org/


And look at that: a totally different IP address.

And here is a different prove.


If you open your web browser and visit the Google search or Youtube or whatever Google service, you are greeted in a different language. Here I was greeted in French. Meaning that Google thinks my location is somewhere in France !!

Extra safety

Those of you who have worked with a TOR browser know that a TOR browser connects to a TOR server, that connects to another TOR server and that again connects to yet another TOR server. And that last server connects to the website you wanted to have a look at. For safety all these connections are encrypted.

This way you can not easily be traced.

For extra safety you can use your TOR browser with the VPN.

Just make sure to start the VPN connection first and then start your TOR browser. That way your TOR browser connects to a TOR server through your VPN connection which gives you an encrypted communication line upon an encrypted line. So a double encrypted and untraceable connection.

So if you, for example, want to see a tv show or series that is only available for US citizens within the US connect to a VPN server in the US. And if you connect through a TOR browser make sure the last server in the range is also a US TOR server.

Safe surfing
till next time
have fun


Luc Volders

Friday, April 10, 2026

To MIP or not to MIP : installing libraries in MicroPython

For an index to all my stories click this text.

The world changes, and so does the MicroPython language.
In the latest versions of MicroPython a new method to install libraries was introduced : MIP And it is supposed to make life less complicated.

How I use(d) to install libraries.

When I need a display in a MicroPython project I often use a TM1637 quad 7 segment display. To be able to use this display you'll need a library.

THE place to find libraries for MicroPython is Mike Causers repo at Github:
https://github.com/mcauser/awesome-micropython


Scrolling through this huge list of libraries the TM1637 library is in the LED Segment section (about half way down the page).

Clicking micropython-tm1637 brings you to the github page that contains the driver.


At that page I click on the drivers entry being tm1637.py


This is the MicroPython driver for the TM1637. As you can see it is actually just a MicroPython program.


I copy the complete code and paste it into Thonny.


Then I save this in the lib folder using the exact name the library has. In this case tm1637.py


And there it is, in the Pico's memory, in the lib folder, ready to use.

Using MIP

Now let's see how the new method works. MIP is supposed to make this all less complicated. Well let's have a look.

First step is to know where the library is located.
So we need to look at the same library list mentioned above.
Then we need to scroll downwards to the LED Segment section.
Like above described we need to click on the drivers entry in the list.
And then click on the actual driver.

So until now everything is the same.
But we now have the exact URL where the driver is located:
https://github.com/mcauser/micropython-tm1637/tm1637.py

We can use that with MIP.
MIP knows Github so we can leave https://github.com/ out and just use github: like this:

mip.install("github:mcauser/micropython-tm1637/tm1637.py")

But first we need to install MIP.


So these are the lines that are needed:

import mip

mip.install("github:mcauser/micropython-tm1637/tm1637.py")



And this is the output I got.
It did not work.

Of course it did not work !!!  MIP gets the driver from the internet, so you have to activate Wifi first.........

import network
import time

ssid = "Ziggo2903181"
pw = "ptzbB2ohKbgs7agp"

print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)
print('Waiting for connection.',end="")
while wifi.isconnected() == False:
    time.sleep(1)
    print('', end='.')
print("")

ip = wifi.ifconfig()[0]

print("Connected with IP adress : "+ip)

import mip

mip.install("github:mcauser/micropython-tm1637/tm1637.py")



And now it works.


The library is automatically downloaded and placed in the /lib folder.

Conclusion:

Actually it is a lot of hassle.
The first steps are the same as in my original method. Then you have to make sure you got the URL right and then write a small program in MicroPython that activates the Wifi.
To be frank: by that time I have already copied and pasted and saved the library by hand.

Mip comes from the land of Python. And Python runs mostly on desktop computers and notebooks. These machines have an internet connection standard activated and then it is a lot less hassle.
On our microcontrollers Wifi is not standard activated.

Looking at the start of this story:
The world changes and MicroPython changes to.
But not all changes are for the better. Luckily the old method still works.

Till next time
have fun

Luc Volders

Friday, April 3, 2026

Trolling google with a Pico

For an index to all my stories click this text.

In some previous stories on this weblog I showed how the Raspberry Pi Pico could produce audio. And not just plain audio but really decent audio.

And then when I was goofing around I had this weird idea.
How about the Raspberry Pi Pico activating my Google Home mini..........

If you want to try this and Troll your own Google you need the following setup:

- A raspberry Pi Pico with audio like described in this story:
https://lucstechblog.blogspot.com/2024/10/pico-audio-part-3.html
- A small active speaker (like a computer speaker)
- Preferably an SD card attached to the Raspberry Pi Pico like this story showed:
https://lucstechblog.blogspot.com/2025/01/pico-sdcard-part-1-hardware.html
And this story for the software:
https://lucstechblog.blogspot.com/2025/01/pico-sd-card-part-2-software.html

Next to that you will need the Audacity software to record your own voice saying ok google ...... and converting it into an 8K wav file. Audacity is free and available on Linux and Windows. I wrote a story on how to use audacity especially for this purpose which you can read here:
https://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

The breadboard setup

I used my audio setup from the previous stories. This includes 3 buttons and an SD-card.



For the example presented here you only need the two buttons attached to GP18 and GP19. And you do not need the oled screen.
You could even do without the SD-card as both files together take less than 200k. However working with an SD card is so easy and convenient that I highly recommend it for many projects, but certainly for audio projects.

For all the details on this setup read this story:
https://lucstechblog.blogspot.com/2025/02/raspberry-pi-pico-audio-player.html

Record the "Ok-Google" sentence.

First thing you need to do is to record some sentences that you want your Google Home (or nest) to react on. I used Audacity to record two sentences and convert them to an 8K WAV file. The sentences I used are:

- OK Google, is it going to rain in Amsterdam today
- OK Google, what is the time.

Make sure you pause for a second or so after OK Google and before speaking the rest. Your Google home needs some time to wake up.

If you are not sure how to record the sentences and convert them to an 8K wav file please read this story:
https://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

Transfer the recorded sentences to the SD card.

Next step is of course to transfer the recorded sentences to your SD card. You can do that physically by attaching the SD card to your computer with an SD-card reader.
Another option is to use Thonny to transfer the recorded sounds to the SD=card if that is still attached to your Pico.

I put the sounds in "/sd/Sounds2" and named them okgoogletime.wav and okgooglerain.wav.
You can of course put these in any directory you want and name them as you like. Just make sure to adjust the upocoming program to your own settings.

The program

The program is easy to follow. It just constantly tests whether one of the buttons is pressed and if so it speaks out the recorded sentences.

import os
from machine import SPI, Pin
import sdcard

spi = SPI(1,sck=Pin(14), mosi=Pin(15), miso=Pin(12))
cs = Pin(13)
sd = sdcard.SDCard(spi, cs)

os.mount(sd, '/sd')

but01=machine.Pin(18, machine.Pin.IN)
but02=machine.Pin(19, machine.Pin.IN)

from wavePlayer import wavePlayer
import time

player = wavePlayer()

while True:
    if (but01.value()==0) :
        player.play('sd/Sounds2/okgooglerain.wav')
          
    if (but02.value()==0) :
        player.play('sd/Sounds2/okgoogletime.wav')

        
That is all. The program is based on my previous stories about playing audio and attaching an SD-card to the Pico. In these stories you will also find the links to the required libraries.

That's all.

Now just press one of the buttons and hear your voice speaking the sentences. And then just wait a moment and your Google Home will react.

The video that demonstrates it



The only thing now to do is to find a practical purpose for this. But for now it is fun to troll your google assistant a bit.

Till next time
have fun

Luc Volders




Friday, March 20, 2026

A stupid MicroPython quirk

For an index to all my stories click this text

Here is a small and stupid MicroPython / Python quirk.
I blundered into this when I made an error in one of my programs.

Both MicroPython and Python have this stupid quirk: they see _ (underscore) as a normal variable.

for _ in range(10):
       print("This is stupid :")
       print(_)


Just look at this example.
You would not expect this to work. But look at the output in Thonny's shell:


So be careful with your variables. A typo can have strange results.

Till next time,
have fun

Luc Volders

Friday, March 6, 2026

Make Gemini speak

For an index to all my stories click this text.

In the previous story I showed how to build a webpage on which you could type a question. The question was then send to a simple AI system and then spoken out.
You can read that story here: https://lucstechblog.blogspot.com/2026/02/2a-speaking-ai.html

It works but has some flaws. It uses a special service to avoid a CORS error. And that service sometimes is so busy, that you need to retry sending your question a few times. Which is annoying.

I had better luck with Google's Gemini AI.
I know that there are people out there that hate Google. But I actually like them. And their AI has a great free tier, and it works great.
So I am going to rebuild the webpage with Gemini.

To use the following program you will need to obtain an API key from VoiceRSS. Read this story that tells you how to get it: https://lucstechblog.blogspot.com/2026/02/text-to-speech-with-voicerss.html

And you'll need an API key for using Google's Gemini. Read this story that tells how to get it: https://lucstechblog.blogspot.com/2026/02/build-webpage-with-gemini-ai-as-your.html


Sidenote.

Javascript is a fun language which is not very difficult to learn. And you get instant results in your webbrowser. The language is useful for all kinds of projects, including IOT projects of which you find several on this weblog.
To make programming in Javascript easier I collected over 500 tips and tricks and bundled them in a book. The book is distributed world-wide by amazon.com


Click here to learn more about this book or to order it.

So what we are going to do is to build a webpage on which you can type a question. That question is send to Gemini and the answer is spoken out aloud. So turn up the volume of your computers speakers and let's go.

And here is the complete program.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Gemini Web Chat Demo</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      background: #f7f7f7;
      padding: 2rem;
    }
    #container {
      background: #fff;
      padding: 1.5rem;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0,0,0,0.1);
      max-width: 600px;
      margin: auto;
    }
    textarea {
      width: 100%;
      font-family: inherit;
      font-size: 1rem;
      padding: 0.6rem;
      border: 1px solid #ccc;
      border-radius: 6px;
      resize: none;           /* user can’t drag resize */
      overflow: hidden;       /* hide scrollbar */
      min-height: 2.5rem;
    }
    button {
      margin-top: 0.5rem;
      padding: 0.4rem 1rem;
    }
    #response {
      margin-top: 1rem;
      white-space: pre-wrap;
      background: #f0f0f0;
      padding: 1rem;
      border-radius: 6px;
      min-height: 100px;
    }
  </style>
</head>
<body>
  <div id="container">
    <h2>Ask Gemini</h2>
    <textarea id="userInput" placeholder="Type your question..."></textarea>
    <br>
    <button id="sendBtn">Send</button>

    <h3>Response:</h3>
    <div id="response" contenteditable="true"></div>

    <div id="output"></div>
    <audio id="audioPlayer" controls></audio>

  </div>

  <script>
    const Google_API_KEY = "PUT-YOUR-GEMINI-API-KEY-HERE"; // Replace with your key
    const MODEL = "gemini-2.5-flash";//works
    const textarea = document.getElementById("userInput");
    const sendBtn = document.getElementById("sendBtn");

    // Auto-resize textarea
    textarea.addEventListener("input", () => {
      textarea.style.height = "auto";
      textarea.style.height = textarea.scrollHeight + "px";
    });

    sendBtn.addEventListener("click", async () => {
      const input = textarea.value.trim();
      if (!input) return alert("Please enter a question.");
      const responseDiv = document.getElementById("response");
      responseDiv.textContent = "Loading...";

      try {
        const res = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${Google_API_KEY}`,
          {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
            contents: [{ parts: [{ text: input }] }] // ✅ send user input
            })
          }
    );


        const data = await res.json();
        const text = data?.candidates?.[0]?.content?.parts?.[0]?.text || "(No response)";
        responseDiv.textContent = text;


        let rec_ans = text || "";
        rec_ans = rec_ans.replace(/[^A-Za-z0-9 \n.,!?\\*+\-%@$&:<>()[\]{}"`]/g, "").trim();

        //document.getElementById("output").textContent = rec_ans;
        //console.log("Received Answer:", rec_ans);

        const VoiceRSS_API_KEY = 'PUT=VOICERSS-API-KEY-HERE';
        const url = 'https://api.voicerss.org/';

        const params = new URLSearchParams({
          key: VoiceRSS_API_KEY,
          hl: 'en-us',
          v: 'Amy',
          f: '8khz_16bit_mono',
          src: rec_ans
        });

        const ttsResponse = await fetch(url, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: params
        });

        if (!ttsResponse.ok) {
          console.error('❌ TTS request failed:', ttsResponse.status);
          return;
        }

        const audioBlob = await ttsResponse.blob();
        const audioUrl = URL.createObjectURL(audioBlob);

        const audioPlayer = document.getElementById("audioPlayer");
        audioPlayer.src = audioUrl;

        audioPlayer.play().catch(err => console.error("🎧 Playback error:", err));

        console.log("🎵 Playing audio...");


      // ✅ Automatically trigger audio file download (no visible button)
      const downloadLink = document.createElement('a');
      downloadLink.href = audioUrl;
      downloadLink.download = `response_${Date.now()}.mp3`;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      downloadLink.remove(); // clean up the temporary link

      } // end of try part

      catch (err) {
        responseDiv.textContent = "Error: " + err.message;
      }
    });
  </script>
</body>
</html>

I do think there are no real pitfalls here and the code is derived from the code from the previous stories. So I will not go into details here. Please check those previous stories for clarification of the code.
You can also send me a message if you want an explanation about a certain part of the code.

How to use this.

Copy the complete code and paste it in your favorite editor. Then save it as gemini.html Change that name in anything you want as long as it ends on .html
Then open the directory where you saved the program and click on it's icon.
Your default web browser will open with the webpage.


You can now type your question. Then press the Send button
The answer will be written as text in the output field and also spoken.
The audio file is also saved to your download folder, so you can use it for different projects.
Pressing the play button at the bottom of the screen will replay that audio file. So if you misheard the answer you can play it again without sending the question anew to Gemini.

You can restrict the answer from Gemini by putting in your question: "answer in x lines without giving an explanation". Where x can be any number of your choice.

Have fun playing with this. I sure am !!!

Till next time

Luc Volders