SMS Scroller Code

Next its time to load up the SMS-recieving-and-displaying Arduino sketch, included below. Make sure you have the Fona library installed!

Download: file
// Fona + Flora SMSsenger bag
// receives and displays text messages on a 8x32 flex NeoPixel matrix
// tutorial: https://learn.adafruit.com/flora-plus-fona

#include "Wire.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>
#include "Adafruit_FONA.h"

#define FONA_RX 10
#define FONA_TX 9
#define FONA_RST 6

#define PIN 12

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


// Example for NeoPixel Shield.  In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino.  When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order.  The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, PIN,
  NEO_MATRIX_BOTTOM     + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);
const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };

// this is a large buffer for replies
char replybuffer[255];
uint8_t msgLen = 0;              // Empty message
int x    = matrix.width();
int pass = 0; // variable we'll use to keep track of a cycling of colors
bool newMessageCheck = 1; // variable to toggle checking of SMSs after each message scroll
uint8_t n; // variable for the number of SMSs

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

unsigned long prevFrameTime = 0L;             // For animation timing
#define FPS 20                                // Scrolling speed

void setup() {
  Serial.begin(115200);
  Serial.println(F("FONA SMS LCD test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));

  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(40);
  matrix.setTextColor(colors[0]);

  Serial.println(F("Checking FONA"));
  
  // See if the FONA is responding
  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {  // make it slow so its easy to read!  
    //lcd.print("Not found! :(");
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  Serial.println(F("FONA is OK"));
  
  delay(1000);
}



void loop() {

   unsigned long t = millis(); // Current elapsed time, milliseconds.
  // millis() comparisons are used rather than delay() so that animation
  // speed is consistent regardless of message length & other factors.
 if (newMessageCheck == 1){
  while (fona.getNetworkStatus() != 1) {
    Serial.println(F("Waiting 4 signal"));
    Serial.print(".");
    delay(400);
  }
  Serial.println(F("Waiting for SMS"));
  int8_t smsnum = fona.getNumSMS();
  if (smsnum < 0) {
    Serial.println(F("Could not read # SMS"));
    return;
  } else {
    Serial.print(smsnum); 
    Serial.println(F(" SMS's on SIM card!"));
  }
  
  if (smsnum == 0) return;
  else n = smsnum; // there's an SMS! Set index to most recent message
  
     Serial.print(F("\n\rReading SMS #")); Serial.println(n);
     uint16_t len;
     if(!fona.readSMS(n, replybuffer, 250, &len)) {
      // Uh oh failed to read SMS, show error perhaps?
      Serial.println("failed to read SMS");
      //break;
    }
    if (len == 0) {
        Serial.println(F("[empty slot]"));
        n++;
        //continue;
     }
     msgLen = len;
        
     Serial.print(F("***** SMS #")); Serial.print(n); 
     Serial.print(" ("); Serial.print(len); Serial.println(F(") bytes *****"));
     Serial.println(replybuffer);
     Serial.println(F("*****"));
     newMessageCheck = 0;
  }  
   if((t - prevFrameTime) >= (1000L / FPS)) { // Handle scrolling
        matrix.fillScreen(0);
        matrix.setCursor(x, 0);
        matrix.print(replybuffer);
        if(--x < (msgLen * -6)) {
           newMessageCheck = 1;
           x = matrix.width(); // We must repeat!
           if(++pass >= 3) pass = 0;
              matrix.setTextColor(colors[pass]);
        }
      matrix.show();
      prevFrameTime = t;
     }

}
This guide was first published on Nov 18, 2015. It was last updated on Nov 18, 2015. This page (SMS Scroller Code) was last updated on Nov 15, 2019.