Code to integrate a Menu, RTC, Wifi Module (remote) and Small Screen

Hi all,

I've got a project for a word clock that I've written up the basic code for the functionality of the clock and have had working for a while with no issues. Current input is through some potentiometers and rotary encoders.

I'm looking to improve the UI experience in order to better sell these clocks as its currently pretty limited and jankey for want of a better word.

I was hoping to integrate a small screen with 4 way button input and possibly using a small WiFi based remote to change settings and set some basic information on the clock. I started to look into coding it all together but have hit a stumbling block with the size of the code getting too big to fit on an Arduino when using the basic library and thus am looking for someone who can help. This would be paid work.

The key integration parts are:
Arduino Mini (this could be changed if more memory is required)
Screen - SSD1306
Wifi Module - SYN480R
Basic toggle buttons
RTC module - DS3231

Again the clock portion is working (tho maybe needs to be optimized?) so it would be just integrating mainly the screen and UI and the variables to go along with it. Probably pretty basic coding for someone who knows but a bit beyond what i can/want to do.

Let me know if you need any more information. Will provide a full menu and variable breakdown when needed.

Cheers,
Luke

1 Like

A recommendation: a different processor is generally a better solution than trying to shoehorn more code into the same processor. Exception is if the increased parts cost of a bigger CPU is well in excess of the labor cost to use the same CPU.

Definitely not against it if that's the smart choice but the Arduino nano is quite a bit cheaper than even a UNO. Its at the early stage that it can be changed easily enough just the cost difference in the boards then affects the final price.

Main question is whether there actually is a limitation on code as the main memory usage seems to be the library's needed for the menu and display. The Clock portion is only 9000 bytes at the moment and the menu etc wont be super complicated. The hope is someone who's smart on library and memory usage should be able to fit it in comfortably without the potential for issues but i need someone more clued in than me to tell me haha.

1 Like

A tiny single core ESP32-C3 is all you need for a clock. And of course the display.

The ESP can get time off the net, including daylight savings, and keep it accurate between occasional NTP updates. So why the RTC, and why the UI/buttons.

A WiFiManager (portal) can help you with setting up the internet connection.

Basic example in this thread (click).
Leo..

2 Likes

Its a word clock, So it runs an 11 x 11 matrix of RGB LEDs and letters to spell out the words. This then comes with a bunch of different options for lighting the words and background etc and some options to run just visual programs that look good but don't tell the time. I want to stay with RTC to avoid having to connect to the internet for simplicity. Also the same reason why i want to run UI/buttons/remote over say an app is so that it just works without breaking later down the line.

What's the budget?

What words will you fit on an 11x11? Maybe something longer?

That's a scrolling matrix, not a word clock.
Leo..

Yes, the simulation is scrolling, but can be adapted by removing the +/- looping. I thought a word clock would have something like: "Nine minutes past the hour of thirteen hours" or something similar... or is it a WWT clock with voice; "At the tone, the time will be thirteen hours..."

Thank you... I see now... the 11x11 are behind the words (even though the letter grid is 12 x 9).

I'm open to quotes, It really depends on how long it takes but a couple of hundred is no sweat. I believe its a fairly simple and straight forward coding project so shouldn't take over a day.

Yeah its a modified layout to what Wawa posted that ended up being 11 x 11 but exactly that style

Are you doing this for commercial use? Doing a project purely for fun is something completely different from making a product someone is willing to pay for.

You need to consider the fact that there has to be a custom PCB made for this eventually.

Size, power, BOM cost, availability of components etc also matter in a commercial product.

Have you taken any of that into consideration?

Here is a start to the code. The simulation is not important, but does show the complete code is not an advanced task. Changing it from 12x9 to 11x11 is simple (pixels count from 0 to 121 rather than 0 to 12x9). I would improve upon this simulation by creating ONLY ONE function to light the words (here I created a function for each word) to (1) identify the starting pixel, (2) identify the ending pixel and (3) change the color (live/dynamically or time of day). The code in the simulation can be found below the images.

Two files for WOKWI.COM

sketch.ino
// https://forum.arduino.cc/t/code-to-integrate-a-menu-rtc-wifi-module-remote-and-small-screen/1286493/

#include <FastLED.h> // http://fastled.io/docs/files.html

#define ROWS 16 // matrix rows
#define COLS 16 // matrix columns
#define NUMPIX (ROWS * COLS) // the full matrix
#define PIXPIN 5 // Arduino data/digital pin
#define MAXBRIGHT 255 // pixels brightness, 0 - 255 
CRGB pix[NUMPIX]; // create object to control [NUMPIX]

void setup() {
  FastLED.addLeds<WS2812B, PIXPIN, GRB>(pix, NUMPIX);
  FastLED.setBrightness(MAXBRIGHT);
  FastLED.clear(); // clear pixel buffer
  FastLED.show(); // display cleared buffer

  it();
  is();
  quarter();
  past();
  five();
  
  FastLED.show();
}

void loop() {
}

void it() {
  for (int i = 0; i < 2; i++) {
    pix[i] = CRGB::Yellow;
  }
}

void is() {
  for (int i = 3; i < 5; i++) {
    pix[i] = CRGB::Yellow;
  }
}

void quarter() {
  for (int i = 12; i < 19; i++) {
    pix[i] = CRGB::Yellow;
  }
}

void past() {
  for (int i = 32; i < 36; i++) {
    pix[i] = CRGB::Yellow;
  }
}

void five() {
  for (int i = 60; i < 64; i++) {
    pix[i] = CRGB::Yellow;
  }
}

diagram.json
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 52.8, "left": -19.7, "attrs": {} },
    {
      "type": "wokwi-neopixel-matrix",
      "id": "ring1",
      "top": -165.72,
      "left": -88.65,
      "attrs": { "pixleate": "1", "rows": "9", "cols": "12" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo1",
      "top": -172.8,
      "left": -86.4,
      "attrs": { "text": "I\nQ\nT\nT\nT\nF\nE\nN\nT" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo2",
      "top": -172.8,
      "left": -57.6,
      "attrs": { "text": "T\nU\nE\nO\nW\nI\nI\nE\nI" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo3",
      "top": -172.8,
      "left": -28.8,
      "attrs": { "text": "T\nA\nN\nE\nO\nV\nG\nL\nO" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo4",
      "top": -172.8,
      "left": -9.6,
      "attrs": { "text": "I\nR\nF\nT\nT\nE\nH\nE\n'" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo5",
      "top": -172.8,
      "left": 19.2,
      "attrs": { "text": "S\nT\nI\nW\nH\nS\nT\nV\nC" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo6",
      "top": -172.8,
      "left": 38.4,
      "attrs": { "text": "I\nE\nV\nE\nR\nI\nN\nE\nL" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo7",
      "top": -172.8,
      "left": 67.2,
      "attrs": { "text": "T\nR\nE\nL\nE\nX\nI\nN\nO" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo8",
      "top": -172.8,
      "left": 96,
      "attrs": { "text": "W\nH\nE\nV\nE\nS\nN\nD\nC" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo9",
      "top": -172.8,
      "left": 115.2,
      "attrs": { "text": "E\nA\nP\nE\nF\nE\nE\nD\nK" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo10",
      "top": -172.8,
      "left": 144,
      "attrs": { "text": "N\nL\nA\nO\nO\nV\nT\nA\nM" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo11",
      "top": -172.8,
      "left": 172.8,
      "attrs": { "text": "T\nF\nS\nN\nU\nE\nE\nT\nE" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo12",
      "top": -172.8,
      "left": 192,
      "attrs": { "text": "Y\nM\nT\nE\nR\nN\nN\nE\nA" }
    },
    { "type": "wokwi-vcc", "id": "vcc1", "top": 10.36, "left": 211.2, "attrs": {} },
    { "type": "wokwi-gnd", "id": "gnd1", "top": 57.6, "left": -96.6, "attrs": {} }
  ],
  "connections": [
    [ "gnd1:GND", "ring1:GND", "black", [ "v-9.6", "h76.8" ] ],
    [ "vcc1:VCC", "ring1:VCC", "red", [ "v9.6", "h-153.6" ] ],
    [ "ring1:DIN", "nano:5", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}

Thanks, I've done the code for the clock as I've written pretty much as you described. That's no issue. More integrating and reducing library's at the moment.

Going for ATtiny85?

Updated word clock to use one "say" function... added "sayitall()" function...

// https://forum.arduino.cc/t/code-to-integrate-a-menu-rtc-wifi-module-remote-and-small-screen/1286493/

#include <FastLED.h> // http://fastled.io/docs/files.html

#define ROWS 16 // matrix rows
#define COLS 16 // matrix columns
#define NUMPIX (ROWS * COLS) // the full matrix
#define PIXPIN 5 // Arduino data/digital pin
#define MAXBRIGHT 255 // pixels brightness, 0 - 255 
CRGB pix[NUMPIX]; // create object to control [NUMPIX]

void setup() {
  FastLED.addLeds<WS2812B, PIXPIN, GRB>(pix, NUMPIX);
  FastLED.setBrightness(MAXBRIGHT);
  FastLED.clear(); // clear pixel buffer
  FastLED.show(); // display cleared buffer

  sayitall(); // show words in sequence
}

void loop() {
}

void say(byte first, byte size) {
  int r = 255, g = 255, b = 0; // yellow
  for (int i = first; i < first + size; i++) {
    pix[i] = CRGB(r, g, b);
  }

  FastLED.show();
  delay(500);
  FastLED.clear();
  FastLED.show();
}

void sayitall() {
  say( 0,  2); // it
  say( 3,  2); // is

  say(32, 4); // past
  say(36, 2); // to

  say(45, 3); // one
  say(48, 3); // two
  say(51, 5); // three
  say(56, 4); // four
  say(60, 4); // five
  say(64, 3); // six
  say(67, 5); // seven
  say(72, 5); // eight
  say(77, 4); // nine
  say(81, 3); // ten
  say(85, 6); // eleven
  say(39, 6); // twelve

  say(12, 7); // quarter
  say( 6, 6); // twenty
  say(19, 4); // half
}
1 Like

How are you going to do that without a WiFi or BT enabled board.
A thumbnail-sized ESP32-C3 with (optional) RTC should be able to do all of this. And run a web server (with or without internet), so you can set everything with a smartphone. Plenty of memory, and it also does Bluetooth.
Leo..

ESP32 can also play a .wav file and speak the time with pretty high fidelity. Which is what I first thought of when I saw the "say()" function.

Wordclock using RTC to show current hour (need to change code to light it only one time). Unfinished.