Ceas de grădină

Orice grădină are pe lângă plante și flori și diverse obiecte care aduc un farmec suplimentar aranjamentelor naturale: felinare, pietre decorative, pitici de grădină etc. În cadrul materialului de față vă propunem realizarea unui obiect inedit – un felinar cu funcționalități de ceas – un felinar ce va lumina doar la oră exactă clipind de un număr de ori egal cu ora (un orologiu luminos).

Pentru implementarea sistemului vom utiliza o placă de dezvoltare A-Star 328PB, placă de dezvoltare compatibilă Arduino dar care este echipată cu ultima variantă de microcontroler ATmega328. Pentru a putea păstra ora exactă sistemul va include o componentă RTC ce se va interconecta cu placa de dezvoltare prin intermediul magistralei I2C. Pentru a genera o lumină suficient de puternică și pentru a putea controla inclusiv culoarea sistemul va utiliza o componentă de 7 LED-uri RGB WS2812 mai exact Neopixel Jewel 7 x WS2817 5050 RGB LED. Schema de interconectare dintre componentele sistemului este următoarea:

2

Toate componentele sistemului se vor alimenta la 5V. Se poate utiliza un alimentator de rețea de 5V minim 1A sau, pentru portabilitate, o baterie externă USB de minim 1000mAh. Modulul RTC se va conecta la placa de dezvoltare utilizând pinii A4 (SDA) și A5 (SCL). Componenta Neopixel Jewel va utiliza pinul 9 al plăcii de dezvoltare.

Pentru programarea plăcii de dezvoltare, ca și în cazul Arduino Pro Mini, este necesară utilizarea unui programator FTDI de 5V. Pentru punerea în funcțiune și utilizarea plăcii de dezvoltare A-Star 328PB se recomandă parcurgere documentației oficiale a producătorului.

Programul a fost dezvoltat și testat utilizând Arduino IDE 1.8.5 având instalate extensia Pololu A-Star Boards 4.0.2 și biblioteca FastLED 3.1.6 (pentru controlul componentei Neopixel Jewel).

#include <Wire.h>

#define DS1307_I2C_ADDRESS 0x68

#include “FastLED.h”

#define NUM_LEDS 7

#define DATA_PIN 9

CRGB leds[NUM_LEDS];

În cadrul secțiunii setup() se vor inițializa obiectele de comunicație și control pentru modulul RTC și componenta Neopixel Jewel.

void setup() {

  Wire.begin();

  delay(1000);

  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  delay(1000); }

Secțiunea loop() va implementa comportamentul de orologiu luminos: va citi data furnizată de modulul RTC, dacă este oră fixă (minute<1) se vor aprinde și stinge cele 7 LED-uri de un număr de ori egal cu ora, culoarea LED-urilor va fi roșie, verde, albastră în mod ciclic în funcție de oră. Comportamentul poate fi modificat după propria imaginație mai ales având în vedere faptul că LED-urile utilizate acceptă o paletă variată de culori. Funcțiile bcdToDec și getDateDs1307 sunt utilizate pentru a citi ora din modulul RTC.

void loop() {

   byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

   getDateDs1307(&second, &minute, &hour, &dayOfWeek,&dayOfMonth, &month, &year);

   if (minute<1) {

      for (int j=0; j<hour; j++) {

        for (int i=0; i<NUM_LEDS; i++) {

          int r = hour % 3;

          switch (r) {

          case 0:

              leds[i].setRGB(255,0,0);

          case 1:

              leds[i].setRGB(0,255,0);

          case 2:

              leds[i].setRGB(0,0,255);

          }

          FastLED.show();

          delay(10);

        }

        FastLED.show();

        delay(5000);

        for (int i=0; i<NUM_LEDS; i++) {

            leds[i].setRGB(0,0,0);

            FastLED.show();

            delay(10);

        }

        FastLED.show();

        delay(5000);

      }

   }

   delay(10000);

}

byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); }

void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) {

  Wire.beginTransmission(DS1307_I2C_ADDRESS);

  Wire.write(0);

  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);

  *minute     = bcdToDec(Wire.read());

  *hour       = bcdToDec(Wire.read() & 0x3f);

  *dayOfWeek  = bcdToDec(Wire.read());

  *dayOfMonth = bcdToDec(Wire.read());

  *month      = bcdToDec(Wire.read());

  *year       = bcdToDec(Wire.read()); }

Pentru a seta data și ora în modulul RTC se poate rula înainte de încărcarea programului principal un program ce setează informațiile în memoria internă a modulului RTC. Acest lucru se face o singură dată, modulul RTC va contoriza trecerea timpului și va păstra data și ora chiar în lipsa alimentării cu energie a sistemului grație bateriei proprii. Programul ce setează modulul RTC este (trebuie trecută dată și ora exactă la care se rulează programul – instrucțiunea setDateDs1307):

#include <Wire.h>

#define DS1307_I2C_ADDRESS 0x68

#include “FastLED.h”

#define NUM_LEDS 7

#define DATA_PIN 9

CRGB leds[NUM_LEDS];

void setup() {

  Wire.begin();

  delay(1000);

  setDateDs1307(0, 59, 19, 3,4, 6, 2018); }

void loop() {

}

byte decToBcd(byte val) { return ((val/10*16) + (val%10)); }

void setDateDs1307(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {

      Wire.beginTransmission(DS1307_I2C_ADDRESS);

      Wire.write(byte(0));

      Wire.write(decToBcd(second));

      Wire.write(decToBcd(minute));

      Wire.write(decToBcd(hour));

      Wire.write(decToBcd(dayOfWeek));

      Wire.write(decToBcd(dayOfMonth));

      Wire.write(decToBcd(month));

      Wire.write(decToBcd(year));

      Wire.write(byte(0));

      Wire.endTransmission();     }

Sistemul poate fi pus într-un felinar de grădină (putem utiliza felinarul ca și carcasă pentru sistemul nostru) sau, varianta mai simplă, putem folosi un borcan ermetic ce poate ulterior să fie pictat.