Introduction: Text Message in a Bottle
What is It
How often have you sent off a message in a bottle, only to realise, as it floats out of sight, that you regret the contents of your message? Well, with the Text Message in a Bottle (TM) that will no longer be a problem! You can update your message at any time, just by sending a text. Fantastic!
Why Did I Build It
I have been following the oodles of submissions to the LinkIt One MediaTek Collection, and most of them are without housings, even projects like weather stations that are ostensibly for use outdoors, so I decided to demonstrate a simple waterproof project with off the (kitchen) shelf parts.
Features (or, what you can learn in this Instructable)
- Battery Powered
- Solar Charged
- Display battery/charging status on one line of a 16x2 character LCD
- Receives SMS
- Display scrolling SMS on the other line of a 16x2 character LCD
Other Ideas/Complications
My original plan was to make a completely self-contained, solar-powered, WiFi-hotspot-in-a-jar, that would allow people to connect and download files or leave notes on a web server or something, but unfortunately the LinkIt One does not support running the WiFi in Access Point (AP) mode.
My next idea was to the same sort of thing using Bluetooth, like some shops do, where they send you an image or message when you come in range (proximity marketing), but it seems that this is also not yet in the API.
Step 1: Components Used
Linkit One
The MediaTek LinkIt One is an Arduino-compatible board with some very cool features built in, in this project we are using the built-in GSM for receiving SMS messages as well as the built-in battery charger to charge the included battery.
Sim Card
A prepaid sim-card that can receive text messages. Preferably one without a PIN.
Solar Panels
I used 3 long narrow 8-10V solar panels of approximately 1W output, I got them out of broken/obsolete equipment, so I don't have any info at all on them.
You should be able to buy things like this easily on sites such as Aliexpress if you don't mind waiting for the shipping.
DC-DC Converter/Regulator
I chose the Power Trends PT78ST105S because I had one lying around, here are its specs
Input Voltage: 9-38V
Output Voltage: 5V
Output Current: 1.5A
Duct Tape
I used a knock-off of Duct Tape to turn the three solar panels into a foldable unit, as well as to attach the various modules to the back of the panels. It looks like a hack job when open, but when folded up it is rather neat.
Jar
Jars designed for pickling or jams are ideal, because they have wide necks. I couldn't find a large enough Mason Jar, which i think would be the best, so I chose a 1.5l swing top instead.
Step 2: Wire Solar Panels and Converter
The Easy Way
There is an premade solution of course if you don't want to build the circuit yourself, just search places like aliexpress for solar-powered cellphone chargers, swipe your credit card and 60 days later you will have a solution.
The Hard Way
I wrote an in-depth Instructable on powering your LinkIt One via solar power over here, so I recommend reading over that if you need more details.
Wiring The Panels
Since I arranged my panels in a triangular tube shape (like a Toblerone), I knew that at least one would always be considerably more shaded than the others.
This is a complicated topic (which you can read all about over here), but the key issue is that
- The output current of a string of cells in series is limited to the current generating capability of the most shaded cell.
- The output voltage is roughly constant above a certain illumination level.
If the cells are all in series and one of them is shaded, the total current flow will be restricted, but if they are in parallel then the cells that are receiving light will be able to deliver their generated power unimpeded.
Choosing the 5V Converter
The LinkIt One has an on-board battery charger, which expects to be provided with a nice steady 5V via the USB port.
The output voltage of a solar panel varies slightly with the amount of illumination it receives, but it is almost always going to be more than 5V, so we need to convert it down using a switch-mode regulator.
There are oodles of options, you just need to make sure that the one you choose meets the following requirements
Input Voltage (from the panels)
Make sure that the expected output voltage of your solar panel fall within the input voltage range of the switch-mode regulator
Output Voltage (to the LinkIt One)
5V, no more, no less
Output Current
The regulator must be able to handle the current that you are putting through it.
Take a look at your solar panel's current rating (or determine it from power/voltage), this will be the maximum input current, and the regulator must be able to handle it.
Ignoring inefficiencies, output current will be (input current)*(input voltage/output voltage), and the regulator must be able to handle it.
Example Regulator 1
I chose the Power Trends PT78ST105S because I had one lying around, here are its specs
Input Voltage: 9-38V
Output Voltage: 5V
Output Current: 1.5A
Example Regulator 2
I am also quite a fan of these little guys, but note here how the input voltage is 14V minimum, which means that I would have needed two of my 8V solar panels in series.
Input Voltage: 14-28V
Output Voltage: 5V
Output Current: 500mA
Wiring the 5V Converter
You will need a micro-USB connector, I got one off a broken cellphone charger.
The wiring is as follows
- Positive output of the solar panel to Vin on the regulator
- Negative output of the solar panel to GND on the regulator
- Vout from the regulator goes to +5V on the USB connector
- GND from the regulator goes to GND on the USB connector
Step 3: Connect the 16x2 LCD
Make the connections
I used a 16x2 LCD that I had scavenged out of some old electronics, but if you have a 16x4 or similar that would work too, anything based on the HD44780 chip will work with this code.
The following table shows the purposes of all of the pins, as well as the connections to make to the LinkIt One.
If the LCD has a backlight then it will probably be an LED across pins 15 and 15, but I would consider it a waste of power in this application.
LCD Pin Number | Symbol | Function | Connection |
---|---|---|---|
1 | Vss | GND | LinkIt One GND |
2 | Vdd | +5V | LinkIt One 5V |
3 | Vo | Contrast Adjustment | GND (via 150Ohm resistor) |
4 | RS | Register Select | LinkIt One D13 |
5 | R/W | Read/Write | GND |
6 | E | Enable Signal | LinkIt One D12 |
7 | DB0 | Data Bus Line | N/C |
8 | DB1 | Data Bus Line | N/C |
9 | DB2 | Data Bus Line | N/C |
10 | DB3 | Data Bus Line | N/C |
11 | DB4 | Data Bus Line | LinkIt One D11 |
12 | DB5 | Data Bus Line | LinkIt One D10 |
13 | DB6 | Data Bus Line | LinkIt One D09 |
14 | DB7 | Data Bus Line | LinkIt One D08 |
If you want more information on connecting up a 16x2 LCD, then Adafruit's well documented articles are always a good start.
Test
Once you have connected these pins and powered up the LinkIt via USB or battery you should see a single row of black blocks on the LCD. If you don't then something is wrong, check all the connections and consider adjusting the contrast resistor, connecting pin 3 to GND directly will set maximum contrast.
Now you are ready to write some code to control the display.
Step 4: Write Program
IMPORTANT NOTE: LiquidCrystal Library
At the time of writing this the LinkIt One IDE comes with version 1.6.5 of the Arduino IDE, which happens to be one where the LiquidCrystal Library that we are using is broken. Look at this Instructable on how to replace the LiquidCrystal files with working ones.
Intro
I am assuming that you have already set up your Arduino IDE to work with the LinkIt One, if not, have a look at the "getting started" guide over here.
I have attached my final code to this step, you should be able to read through it and its comments to get a pretty good idea of how it works. I will describe the important segments here.
Import Libraries
The first step is to included the various libraries that are going to be used.
#include <LGSM.h> #include <LiquidCrystal.h> #include <LBattery.h>
Define Variables
Next we define various global variables that will be used in the program. You will see that a number of them are defined as "char name[x]" which means that they are an array of x characters, which is use to store things like the text message or a status message.
//these variables are for the sms char smsContent[160]; int smsLength = 0; char smsSender[20]; boolean newMessage = LOW; //variables for battery status char statusMessage[16]; // initialize the LCD library with the numbers of the interface pins // lcd(RS, Enable, DataBus4, DataBus5, DataBus6, DataBus7) LiquidCrystal lcd(13, 12, 11, 10, 9, 8); int scrollInterval = 500; unsigned long lastUpdate = 0; int msgStartChar = 0; int lcdStartChar = 0;
setup() Function
This function is run once when the board boots.
void setup() { lcd.begin(16, 2); // set up the LCD's number of columns and rows: waitForSim(); //wait for simcard to be active Serial.begin(9600); //start the serial port }
waitForSim() Function
The rest of the program won't work if the SIM card is not initialised, so this function just holds the device in a loop, waiting for the SIM to be ready (and printing out little dots on the serial interface, so that you know it hasn't died).
void waitForSim() { Serial.print("waiting for sim"); while (!LSMS.ready()) { delay(250); Serial.print('.'); } Serial.println("Sim Ready"); }
receiveSMS() Function
This function will check if there is a new SMS. If there is one, it is read in, one character at a time, and stored in the smsContent buffer (a character array), then the function returns HIGH (true/1). If there is no new SMS then the function returns LOW (false/0). This allows us to call it as often as we like in the main loop, but only do something if there is a new message.
The "newMessage" boolean is also set to TRUE when a new message is received.
Once the SMS has been read it is removed with the flush() command.
boolean receiveSMS() { //this function will store a new sms in the buffers //or return false if there is no new sms int v; if (LSMS.ready() && LSMS.available()) // Check if there is new SMS { Serial.println("There is new message."); newMessage = HIGH; LSMS.remoteNumber(smsSender, 20); // store sender in buffer smsLength = 0; //storing a new sms while (true) { v = LSMS.read(); if (v < 0) break; smsContent[smsLength] = v; smsLength++; } smsContent[smsLength] = '\0'; smsLength++; LSMS.flush(); // delete message return HIGH; } else { return LOW; } }
chargeStatus() Function
This function creates a 16 character line of text about charge status.
Lbattery.isCharging() returns a 1 if the battery is charging and a 0 if it is not.
Lbattery.level() returns 0,33,66 or 100 depending on the battery's current charge level.
We use the "sprintf" function to format the output from the previous two functions into a nice line of text, which we store in the statusMessage character array for use in the updateDisplay() function.
void chargeStatus() { if(LBattery.isCharging()) { sprintf(statusMessage,"%3d%% charging", LBattery.level() ); } else { sprintf(statusMessage,"%3d%% charged", LBattery.level() ); } }
updateDisplay() Function
This is where all the previously generated content is sent to the LCD for display. It will make the most sense to read it through and look at the inline comments.
The first thing to note is the use of an counter, which takes note of when the screen was last updated (in milliseconds, provided by the Arduino millis() function), and only updates it again if sufficient time (scrollInterval) has elapsed.
The scrolling of the message on the 2nd line is achieved by storing two variables:
msgStartChar
This variable stores which character of the SMS content we are printing first (because we cannot fit the whole 160 character sms on a 16 character line)
lcdStartChar
This variable stores where on the LCD the message starts, since we want the message to scroll in from the right, it cannot always just start on the first character.
Each time that the display is updated we start from the right (position 15) and reduce lcdStartChar until the message is starting on the first character (position 0), this effectively scrolls the message left.
Once the start of the message is at the far left, it needs to scroll off-screen, so we increment the msgStartChar on each update.
void updateDisplay() { //this function will scroll the message on one line and display battery status on the other unsigned long currentMillis = millis(); if (currentMillis - lastUpdate > scrollInterval) { lastUpdate = currentMillis; //get battery status chargeStatus(); lcd.clear(); //first we clear the whole lcd lcd.setCursor(0, 0); //set cursor to first line lcd.print(statusMessage); //print sms on the 2nd line if (newMessage == HIGH) { msgStartChar = 0; //goto first line of new message lcdStartChar = 15; newMessage = LOW; //message dealt with } lcdStartChar = max(0,lcdStartChar - 1); //move one char along on the message (for scrolling) lcd.setCursor(0, 1); //set cursor to bottom line for (int j=0; j<= 15; j++) { if (j < lcdStartChar) { lcd.print(" "); } else if ((msgStartChar+(j-lcdStartChar)) < (smsLength-1)) { lcd.print(smsContent[msgStartChar+(j-lcdStartChar)]); } else { lcd.print(" "); } } if (lcdStartChar <= 0) { msgStartChar++; //move message to the left } if (msgStartChar >= smsLength) { Serial.println("End of message"); //we have reached the end of the message, go back to the start lcdStartChar = 15; msgStartChar = 0; } } }
Attachments
Step 5: Put It All Together
There isn't much to this step, and it will depend largely on the panels, LCD and jar that you choose.
Take a look at my photos, you will see that I connected the three panels using duct tape to form triangular tube that can be easily unfolded to work on the components that are mounted inside.
The fourth side of the triangle.. ok, it's not a triangle anymore... is just a bit of balsa wood cut to size, with a rectangular hole cut for the LCD. I wrapped the balsa in duct tape too to make it prettier.
The unconnected edge of the tube has small magnets under the tape, so that it can easily be opened and unfolded.

Runner Up in the
Brave the Elements Contest

Participated in the
Arduino All The Things! Contest
28 Comments
4 years ago
Perfect. More for Garbage-Island.
6 years ago
Muito boa a idéia, parabéns !!!!!
7 years ago
ossum, very technical indeed. I have a few questions about your instructable. What is or is there a range to the bottle before it can not get a signal to send a text message? For the shaded side of the solar panel while in the bottle, could a small piece of mirror help reflect the sun light to the shaded area? Will the sun damage the LCD screen if its faced up? Will there be any condensation built up in the bottle which could damage the circuit board? Would like to know if these were some of the questions you asked yourself when coming up with this project. This is thinking outside of the box an could be used in different environments. Good luck in the contest.
Reply 7 years ago
Thanks for the questions! As I'm sure you guessed, this wasn't really for sending out to sea, but more a way to demonstrate a completely sealed, self-powered device, so range was not a huge concern. Nevertheless, on land the range would be as good as any cellphone, but in the water it would be reduced (water attenuates RF waves heavily).
The mirror idea is interesting. My gut feeling is that it would be hard to orientate it in a way that provided significant gain when the panel wasn't lit, without blocking that same panel when it would normally be getting full sun. Off the top of my head, if i wanted keep all panels lit I wold arrange them all "upwards" on a pivot (like an axle running from the top to the bottom of the jar), with all of the weight at the bottom, so that they stayed that way no matter which side the jar lay on. Or one could get really high tech and track the sun.
The next two are very good questions, and not ones I had thought about before. Condensation could be easily handled by a bit of silica gel in the bottle, but the LCD damage from UV would be harder to deal with, I guess an E-ink display would be better, it's nice and low power too.
Thanks for making me think :-D It's fun to ponder applications and solutions for projects like this.
Reply 7 years ago
Good suggestions to my questions. For condensation you could use some rice in a piece of woman's stocking shoved to the bottom and that would take up the moister. If the panels were on three sides and the forth the LCD weighted down that would keep panels facing up and LCD out of the UV light. Still a good idea for emergencies or for fun.
7 years ago
Truly a crazy inspired project. Thanks for the great detail!
Reply 7 years ago
I think you will find that most of my projects have a touch of crazy, but inspired is less common ;-) Thanks for the compliment!
7 years ago
Now i know why cargo ships sinks in the ocean. Crashing into piles of littered mason jars.
Reply 7 years ago
On the upside, the survivors would be able to able to get messages...
Don't worry though, I didn't actually let one loose in the sea.
7 years ago
This is one of the greatest ways i've seen to throw my money into the ocean! besides buying a yacht
7 years ago
I think this is one of the coolest ideas I have seen yet. a mini keyboard would have been cool as well. they could message back. Either way I love the idea
Reply 7 years ago
Thanks a lot! I agree some kind of input would be good for any kind of "project in a bottle", the trick would be in sealing it I guess. My one thought was to use an infrared sensor that could detect movement through the glass as a kind of non-contact button.
Reply 7 years ago
Check out the cap touch sensor demos from the Microchip PIC library. You can make touch sensor buttons that work through the glass bottle. I even tried it with 1 inch thick paper.
Well I had asked the salesman at the microchip booth how thick it would work through and he didn't know. I just started piling up his brochures over the demo board until the RGB slider stopped responding.
Answered my question and gave the people around me something to laugh about......
*\
Reply 7 years ago
Capacitive sensor range can go pretty far, heavily depends on the material and the shape of the sensor.
Reply 7 years ago
thanks, I'll check those out!
Reply 7 years ago
or maybe bluetooth with a app the can download to communicate with it
Reply 7 years ago
the only thing that put me off bluetooth was the requirement for an app on the phone (that's why i wanted to serve up a web page via WiFi, it would be perfect to leave dangling from a tree in a public place, just presenting a unsecured access point), but i agree, if the people using it knew what to download then a BT app would be perfect.
7 years ago
This is amazing! It reminds me a little of my Digital Message in a Bottle.
Reply 7 years ago
Just checked it out, now I imagine a combo of the two ideas, a bottle at the bottom of the sea, that charges up via solar power when it is brought to the surface and plays a message.
Reply 7 years ago
Now that's a great idea!