DIY Arduino Pager
Texting like it’s 1990 ;)
TL;DR: The purpose of this project is to allow the user to send short text messages that will then be received on a WiFi ESP8266, and displayed on a Arduino with an LCD screen (shown on the photo below above). The web application was developed in OutSystems.
Parts of this project
- Web Application: lets anyone send the text messages. The backend of the website will connect to an API running on the ESP8266 and send the message through it.
- WeMos D1 R1: cheap but horrible to work with, it’s a WiFi delelopment board, based on the ESP8266 microcontroller. This board will receive incoming requests from the website, and then send the received message to the second development board.
- Arduino Uno: no introductions needed, it’s a development board based on the ATmega328P. This board will receive receive the message from the WeMos D1, and then display it on an LCD display. There’s a beep when a message is received, and 2 buttons to scroll the message up and down.
What I learned
- Don’t buy cheap unsupported development boards, this project would have been way easier with an Arduino 33 IOT and a I2C lcd screen
- How to handle HTTP request/response with a microcontroller
- How to have 2 microcontrollers communicating among them through I2C (even if it’s not the ideal solution)
- How to build a resistor ladder digital-to-analog circuit
- Small steps will take you far!
A bit more detail about the project
While I’m not going to delve into a Instructibles kind of article, I will at least try to break the projects into parts and explain each one of them a little better.
OutSystems Web App
On the web side of this project I decided to go with OutSystems, not only am I very familiar with this development platform, but also because it provides a quick and free way of developing and deploying not only the main UI but also a database, backend, and a quick way to connect safely to my public IP without having to disclose it (I could also have went for a dynamic IP solution like no-ip, but were’s the fun in that, right? ;)
Home page
This is where the user first lands at, it only has two fields and a “Send” button, it’s only purpose it to allow it’s users to send short messages (160 character limit).
When pressing “Send”, the backend will connect to my public IP, and make a HTTP request to it, with the message included in it.
Admin page
If you sign in, you will also be able to access an Admin page. On this Admin page you can:
- Check and update your stored public IP
When clicking on “Get my current IP” the app will make a call to ipify in order to automatically retrieve my current public IP, by pressing “Save” that value will be stored in the database, with a timestamp.
- Check public IP history
This table will show all the previously saved records for the public IP. No purpose other than monitoring and history keeping.
- Message history
This table shows all the received messages, and their status. Also there are options to re-send and to delete the messages.
Backend
The main hurdle on the backend side was to consume the API that is being served from the WeMos D1 microcontroler. Not only APIs are usually consumed using their url address instead of just an IP, but also because this IP will be dynamic, changing from time to time.
To solve this problem a “OnBeforeRequest” action was called before the API request, so that the IP was updated beforehand.
Also it’s worth noting that I added a safeguard on the backend that it only allows sending a message if none was sent for a certain amount of time.
I could, and probably should, have implemented some kind of captcha, but that was already going a bit out of scope for what I wanted to do.
WeMos D1 R1 clone (ESP8266)
When I bought this development board on Aliexpress, at the time I thought I was looking at a shield for Arduino Uno. When I got it I realised it was a stand alone development board, and though “Cool, another Arduino Uno, I will just use this one instead of the other board!”. Boy, was I wrong! I soon discovered this is a very different development board than the Arduino Uno, and just getting the Arduino IDE compiling for it was a pain!
That’s part of the reason I decided on keeping the screen connected to the Arduino Uno, the hardware was already setup, and it would be easier to keep concerns separated. The WeMos D1 would handle the connection to the WiFi network, and the HTTP request/response, and the Arduino Uno would take care of displaying the message.
To handle the connection to local WiFi AP I used one of many readily available code blocks from the internet. The SSID and it’s Password are now hardcoded on the microprocessor. I added changes so that after successfully connected the on-board led lights up.
Same as from before, I used some examples to setup the HTTP request/response handling. Upon accepting an incoming request, it will look and read for a header containing a message. As a mild safety measure, I added code so that it only accepts a new connection after a certain amount of time has passed.
In order to send the message from the WeMos D1 to the Arduino Uno, the I2C protocol was used. This was chosen because both boards support it, integrated hardware serial was already being used for serial monitoring while debugging, and software serial for some reason didn’t want to work. This was simple enough to setup and it only used 2 wires.
Arduino Uno + LCD1602 screen
As mentioned earlier, I had this already laying around from some other project, and it was easier to send the message to it, then to reinstall and configure the screen on the other microcontroller for which I was in no way familiar with (also, the GPIO on the arduino is 5V and the wemos is 3.3V).
For this part of the hardware I only needed to add two buttons to scroll up and down, and to have a speaker that sounds a tone when a message was received.
For the incoming message beep I only had to connect a passive speaker to one of the digital pins, and setup a function to sound a 1479.98 Hz (F#) tone for 200ms. Why F#? Good question! The default Nokia 3210 SMS tone was simply 4 F# notes played in sequence, I tried to replicate this SMS alert sound but then decided to put that feature in backlog because I was sidetracking a lot.
For the buttons I used a resistor ladder, and hence only needed to use 1 analog port (the resistor ladder acts as a digital to analog converter), instead of 2 digital ones. From there I only had to code a function that reads the voltage levels of each state (no button ; button 1 ; button 2), and then outputting the current active state.
One thing that was unexpectedly hard to code, was the text formatting on the tiny screen, so that words are not broken when a line change is needed. We are so used to writing in any UI text box, and for the words wrap neatly to a new line if they don’t fit on the current one, that we don’t even remember someone had to code that. Well, someone did, and it’s not easy ;)
I decided that the easiest way was to have the text aligned to the left, to fit as many words as possible on a given line, and if any word doesn’t fit as a whole in the current line, a new line is started.
In the end it was a very fun project, I could not wait until I could send the TextMe url to all my friends ;) Also I learned a lot of cool new things!