Text Message in a Bottle




About: Electrical Engineer by trade, tinkerer by heart.

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.


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 SymbolFunctionConnection
1VssGNDLinkIt One GND
2Vdd+5VLinkIt One 5V
3VoContrast AdjustmentGND (via 150Ohm resistor)
4RSRegister SelectLinkIt One D13
6EEnable SignalLinkIt One D12
7DB0Data Bus LineN/C
8DB1Data Bus LineN/C
9DB2Data Bus LineN/C
10DB3Data Bus LineN/C
11DB4Data Bus LineLinkIt One D11
12DB5Data Bus LineLinkIt One D10
13DB6Data Bus LineLinkIt One D09
14DB7Data Bus LineLinkIt One D08

If you want more information on connecting up a 16x2 LCD, then Adafruit's well documented articles are always a good start.


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.


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())
  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)
      smsContent[smsLength] = v;
    smsContent[smsLength] = '\0';
    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:


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)


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

    lcd.clear(); //first we clear the whole lcd
    lcd.setCursor(0, 0); //set cursor to first line
    //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)) {
      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;

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.

Brave the Elements Contest

Runner Up in the
Brave the Elements Contest



    • Sensors Contest

      Sensors Contest
    • Fandom Contest

      Fandom Contest
    • Pets Challenge

      Pets Challenge

    28 Discussions


    2 years ago

    Muito boa a idéia, parabéns !!!!!


    3 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.

    2 replies

    Reply 3 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 3 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.


    3 years ago

    Truly a crazy inspired project. Thanks for the great detail!

    1 reply

    Reply 3 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!


    3 years ago

    Now i know why cargo ships sinks in the ocean. Crashing into piles of littered mason jars.

    1 reply

    Reply 3 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.


    3 years ago

    This is one of the greatest ways i've seen to throw my money into the ocean! besides buying a yacht


    3 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

    6 replies

    Reply 3 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 3 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 3 years ago

    Capacitive sensor range can go pretty far, heavily depends on the material and the shape of the sensor.


    Reply 3 years ago

    thanks, I'll check those out!


    Reply 3 years ago

    or maybe bluetooth with a app the can download to communicate with it


    Reply 3 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.


    Reply 3 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.


    3 years ago

    much appreciated!