Sketch Simple Breakout

Arduino Ide sketch code for simple breakout board


#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <hardware/adc.h>

#include "RTClib.h"
#include "Adafruit_FRAM_I2C.h"

// Rotary encoder
#define ENC_A 14
#define ENC_B 15
#define rotencpushpin 11
volatile int counter = 0;
int countersubmenu = 0;
int countersubmenuitem = 0;
int countermenu = 0;
bool submenu = false;
unsigned long _lastIncReadTime = micros();
unsigned long _lastDecReadTime = micros();
int _pauseLength = 150000;
int _fastIncrement = 10;
bool rotencpush = false;
unsigned long lastmillis = 0;

typedef enum {
  PAC_C, // Celsius
  PAC_F, // Fahrenheit
} pactemp_t;

#define pinG2out 2
#define pinG3out 3


#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1  // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES 10  // Number of snowflakes in the animation example

#define LOGO_HEIGHT 16
#define LOGO_WIDTH 32  // This is version one of my Logo as an example. It needs quite a bit of work yet.
static const unsigned char PROGMEM logo_bmp[] = { B00000001, B11110000, B00001111, B10000000,
                                                  B00000011, B11111000, B00011111, B11000000,
                                                  B00000111, B11111100, B00111111, B11100000,
                                                  B00011111, B11111111, B11111111, B11111000,
                                                  B01110000, B00001110, B01110000, B00001110,
                                                  B11100000, B00011100, B00111000, B00000111,
                                                  B11000000, B00111000, B00011100, B00000011,
                                                  B10000000, B01110000, B00001110, B00000001,
                                                  B11000000, B00111000, B00011100, B00000011,
                                                  B11100000, B00011100, B00111100, B00000111,
                                                  B01110000, B00001111, B11110000, B00001110,
                                                  B00011111, B00000111, B11100000, B11111000,
                                                  B00000111, B11111111, B11111111, B11100000,
                                                  B00000111, B11111000, B00011111, B11000000,
                                                  B00000011, B11110000, B00001111, B11000000,
                                                  B00000001, B11100000, B00000111, B10000000 };

#if !defined(ARDUINO_ARCH_RP2040)
#error For RP2040 only
#endif

#if defined(ARDUINO_ARCH_MBED)

#define PIN_SD_MOSI PIN_SPI_MOSI
#define PIN_SD_MISO PIN_SPI_MISO
#define PIN_SD_SCK PIN_SPI_SCK
#define PIN_SD_SS PIN_SPI_SS

#else

#define PIN_SD_MOSI PIN_SPI0_MOSI
#define PIN_SD_MISO PIN_SPI0_MISO
#define PIN_SD_SCK PIN_SPI0_SCK
#define PIN_SD_SS PIN_SPI0_SS

#endif

#define _RP2040_SD_LOGLEVEL_ 4

#define TX_pin 12
#define RX_pin 13

#include <RP2040_SD.h>
File myFile;
File myFileStrtDump;
#define fileName "prim_log.csv"
#define fileNameStrtDump "strtdump.txt"




bool SDok = true;
bool displayok = true;
bool framok = true;
bool rtcok = true;
bool rotenbuttonpush = false;
RTC_DS3231 rtc;
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();

char daysOfTheWeek[7][12] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char daysOfTheWeekFull[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
unsigned long lasttimeloop = 0;

DateTime statusLastTime;
TimeSpan statusTimeDiff = TimeSpan(0,0,0,2);

void testdrawbitmap(void) {
  if (displayok) display.clearDisplay();

  if (displayok) display.drawBitmap(
    (display.width() - LOGO_WIDTH) / 2,
    (display.height() - LOGO_HEIGHT) / 2 - 16,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  if (displayok) display.display();
  //delay(1000);
}



void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  pinMode(pinG2out, OUTPUT);
  pinMode(pinG3out, OUTPUT);

  
  unsigned long startmillis = millis();
  Serial.begin(115200);
  while (!Serial && startmillis + 10000 > millis())
    ;

  Serial1.setRX(RX_pin);
  Serial1.setTX(TX_pin);
  startmillis = millis();
  //Serial1.begin(115200);
  Serial1.begin(9600);
  while (!Serial1 && startmillis + 10000 > millis())
    ;

  Wire.setSDA(20);
  Wire.setSCL(21);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    displayok = false;
    //for(;;); // Don't proceed, loop forever
  }


  if (displayok) testdrawbitmap();

  if(displayok) display.setTextSize(2);      // Normal 1:1 pixel scale
  if(displayok) display.setTextColor(WHITE); // Draw white text
  if(displayok) display.setCursor(12, 44);     // Start at top-left corner
  if(displayok) display.cp437(true);         // Use full 256 char 'Code Page 437' font
  
  if(displayok) display.println("Microtron");
  if(displayok) display.display();

  delay(2000);

  // Invert and restore display, pausing in-between
  if (displayok) display.invertDisplay(true);
  delay(1000);
  if (displayok) display.invertDisplay(false);
  delay(1000);

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    rtcok = false;
    //while (1) delay(10);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }


  if (fram.begin(80, &Wire)) {  // you can stick the new i2c addr in here, e.g. begin(0x51);
    Serial.println("Found I2C FRAM");
  } else {
    Serial.println("I2C FRAM not identified ... check your connections?\r\n");
    //Serial.println("Will continue in case this processor doesn't support repeated start\r\n");
    framok = false;
    //while (1);
  }

  // Read the first byte
  uint8_t test = fram.read(0x0);
  Serial.print("Restarted ");
  Serial.print(test);
  Serial.println(" times");
  // Test write ++
  fram.write(0x0, test + 1);

  if (framok && rtcok && displayok) digitalWrite(LED_BUILTIN, LOW);

  // Set encoder pins and attach interrupts
  pinMode(rotencpushpin, INPUT_PULLUP);
  pinMode(ENC_A, INPUT_PULLUP);
  pinMode(ENC_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENC_A), read_encoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENC_B), read_encoder, CHANGE);

  attachInterrupt(digitalPinToInterrupt(rotencpushpin), encoder_push, FALLING);


  if (!SD.begin()) {
    if (Serial) Serial.println("Initialization failed!");
    SDok = false;
    //return;
  }
  if (!SDok && Serial) Serial.println("SD card initialisation failed. Was the card inserted correctly at start up?");
  else if (Serial) Serial.println("Initialization done.");


  if (SDok) myFile = SD.open(fileName, FILE_WRITE);
  if (SDok) myFileStrtDump = SD.open(fileNameStrtDump, FILE_WRITE);

  DateTime now = rtc.now();
  if (SDok) myFileStrtDump.println(datetimewdayfullstr(now));

  if (SDok) myFileStrtDump.print("No of starts: ");
  if (SDok) myFileStrtDump.println(test);

  

 
  if (SDok) myFileStrtDump.println();

  //myFileStrtDump   // dump startup data here
  if (SDok) myFileStrtDump.flush();





  //DateTime now = rtc.now();
  statusLastTime = now;


  if (Serial) Serial.println(datetimewdayfullstr(now));

  Serial.print(" since midnight 1/1/1970 = ");
  Serial.print(now.unixtime());
  Serial.print("s = ");
  Serial.print(now.unixtime() / 86400L);
  Serial.println("d");

  if (displayok) display.clearDisplay();
  if (displayok) display.setTextSize(2);       // Normal 1:1 pixel scale
  if (displayok) display.setTextColor(WHITE);  // Draw white text
  if (displayok) display.setCursor(0, 0);      // Start at top-left corner
  if (displayok) display.cp437(true);          // Use full 256 char 'Code Page 437' font


  
  if (displayok) display.println(datestr(now));
 
  if (displayok) display.print(daysOfTheWeek[now.dayOfTheWeek()]);
  if (displayok) display.print(", ");
  if (displayok) display.println(rotenbuttonpush ? "push" : "home");

  
  if (displayok) display.println(timestr(now));
  

  test = fram.read(0x0);
  if (displayok) display.print("Start");
  if (displayok) display.print(test);
  if (displayok) display.print(",");
  if (displayok) display.println(counter);



  if (displayok) display.display();
}


volatile bool pushpin = false;
void loop() {

  
  if (pushpin && millis() > lastmillis + 500) {
    rotencpush = true;
    lastmillis = millis();
  }
  pushpin = false;

  if (rotencpush) {
    rotenbuttonpush = true;
    buttonclick();
    rotencpush = false;
  }


  if (!pushpin) {
    rotenbuttonpush = false;
  }

 

  readsensors();
  delay(500);
}

void readsensors() {
  DateTime now = rtc.now();


  if (counter < 0) counter = 0;

  int screen = countermenu;
  if (submenu) {
    countersubmenu = counter;
  } else {
    countermenu = counter % 5;
    screen = countermenu;
  }


  //DateTime now = rtc.now();
  if (screen != 3)
  {
   if(statusLastTime + statusTimeDiff < now)
   {
   if (Serial) Serial.println(datetimewdayfullstr(now));
   

    
    if(Serial) Serial.println("Vsys " + String(analogVsys()));
    if(Serial) Serial.println("Temp " + String(analogReadTemp())); 
    
    
    
    statusLastTime = statusLastTime + statusTimeDiff;
   }
  }

   if (displayok) display.clearDisplay();
   if (displayok) display.setTextSize(2);       // Normal 1:1 pixel scale
   if (displayok) display.setTextColor(WHITE);  // Draw white text
   if (displayok) display.setCursor(0, 0);      // Start at top-left corner
   if (displayok) display.cp437(true);          // Use full 256 char 'Code Page 437' font


  if (screen == 0) {
  } else if (screen == 1) {
    if (!submenu) {
      if (displayok) display.println(datestr(now));
      if (displayok) display.print(daysOfTheWeek[now.dayOfTheWeek()]);
      if (displayok) display.print(", ");
      if (displayok) display.println(rotenbuttonpush ? "push" : "home");
      if (displayok) display.println(timestr(now));

      uint8_t test = fram.read(0x0);
      if (displayok) display.print("Start");
      if (displayok) display.print(test);
      if (displayok) display.print(",");
      if (displayok) display.println(counter);
    } else {
      int screensub = countersubmenu % 3;
      countersubmenuitem = screensub;
      if (screensub == 0) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("0 menu 1");
        if (displayok) display.println("Exit");
      } else if (screensub == 1) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("1 menu 1");
        if (displayok) display.println("Execute");

      } else if (screensub == 2) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("2 menu 1");
        if (displayok) display.println("Execute");
      }
    }
    
  } else if (screen == 2) {
    if (!submenu) {
      if (displayok) display.println("Menu 2");
    }
    else {
      int screensub = countersubmenu % 5;
      countersubmenuitem = screensub;
      if (screensub == 0) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("0 menu 2");
        if (displayok) display.println("Exit");         
      } else if (screensub == 1) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("1 menu 2");
        if (displayok) display.println("G2 High");
        if (displayok) display.println("Execute");
      } else if (screensub == 2) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("2 menu 2");
        if (displayok) display.println("G2 Low");
        if (displayok) display.println("Execute");
      } else if (screensub == 3) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("3 menu 2");
        if (displayok) display.println("G3 High");
        if (displayok) display.println("Execute");
      } else if (screensub == 4) {
        if (displayok) display.println("screensub");
        if (displayok) display.println("4 menu 2");
        if (displayok) display.println("G3 Low");
        if (displayok) display.println("Execute");
      }
    }    
  } else if (screen == 3) {

    
    if(Serial && Serial1)
    {
      
      bool data = false;
     while(Serial1.available() > 0) 
     {
       
       int inByte = Serial1.read();
       Serial.write(inByte);
       data = true;
     }
     if(data) Serial.println("");
     Serial.flush();
    }

    if (submenu) {
      submenu = false; //buttonclick();
      //return;
    }
    if (displayok) display.println("Menu 3");
    if (displayok) display.println("Relay");
    if (displayok) display.println("Serial");
  } else if (screen == 4) {
    if (submenu) {
      submenu = false; //buttonclick();
      //return;
    }
    if (displayok) display.println("Menu 4");
  }


  if (displayok) display.display();
  //delay(500);
}

void encoder_push() {
  pushpin = true;
}

void read_encoder() {
  // Encoder interrupt routine for both pins. Updates counter
  // if they are valid and have rotated a full indent

  static uint8_t old_AB = 3;                                                                  // Lookup table index
  static int8_t encval = 0;                                                                   // Encoder value
  static const int8_t enc_states[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 };  // Lookup table

  old_AB <<= 2;  // Remember previous state

  if (digitalRead(ENC_A)) old_AB |= 0x02;  // Add current state of pin A
  if (digitalRead(ENC_B)) old_AB |= 0x01;  // Add current state of pin B

  encval += enc_states[(old_AB & 0x0f)];

  // Update counter if encoder has rotated a full indent, that is at least 4 steps
  if (encval > 3) {  // Four steps forward
    int changevalue = 1;
    if ((micros() - _lastIncReadTime) < _pauseLength) {
      changevalue = _fastIncrement * changevalue;
    }
    _lastIncReadTime = micros();
    counter = counter + changevalue;  // Update counter
    encval = 0;
  } else if (encval < -3) {  // Four steps backward
    int changevalue = -1;
    if ((micros() - _lastDecReadTime) < _pauseLength) {
      changevalue = _fastIncrement * changevalue;
    }
    _lastDecReadTime = micros();
    counter = counter + changevalue;  // Update counter
    encval = 0;
  }
}

void buttonclick() {
  if (countermenu == 1) {
    if (countersubmenuitem == 1) {
      menu1();
      return;
    }
    if (countersubmenuitem == 2) {
      menu2();
      return;
    }
  }
  if (countermenu == 2) {
    if (countersubmenuitem == 1) {
      menu3();
      return;
    }
    if (countersubmenuitem == 2) {
      menu4();
      return;
    }
    if (countersubmenuitem == 3) {
      menu5();
      return;
    }
    if (countersubmenuitem == 4) {
      menu6();
      return;
    }
  }

  submenu = !submenu;

  if (submenu) {
    counter = countersubmenu;
  } else {
    counter = countermenu;
  }

  if (Serial) Serial.println("buttonclick");
}

void menu1() {
}

void menu2() {
}

void menu3() {
  digitalWrite(pinG2out, HIGH);
}

void menu4() {
  digitalWrite(pinG2out, LOW);
}

void menu5() {
  digitalWrite(pinG3out, HIGH);
}

void menu6() {
  digitalWrite(pinG3out, LOW);
}


String datestr(DateTime now) {
  char buf[30];
  sprintf(buf, "%4u/%02u/%02u", now.year(), now.month(), now.day());
  return buf;
}

String timestr(DateTime now) {
  char buf[30];
  sprintf(buf, "%02u:%02u:%02u", now.hour(), now.minute(), now.second());
  return buf;
}

String daystr(DateTime now) {
  return String(daysOfTheWeek[now.dayOfTheWeek()]);
}

String dayfullstr(DateTime now) {
  return String(daysOfTheWeekFull[now.dayOfTheWeek()]);
}

String datetimestr(DateTime now) {
  return datestr(now) + " " + timestr(now);
}

String datetimewdaystr(DateTime now) {
  return datetimestr(now) + " " + String(daysOfTheWeek[now.dayOfTheWeek()]);
}

String datetimewdayfullstr(DateTime now) {
  return datetimestr(now) + " " + String(daysOfTheWeekFull[now.dayOfTheWeek()]);
}

bool _adc_init = false;
float _vref = 3.3f;
size_t _adc_res = 12;
float analogReadTemp(pactemp_t type) {
	if (!_adc_init) {
		adc_init();
		_adc_init = true;
	}
	adc_set_temp_sensor_enabled(true);
	delay(1); // Allow things to settle.  Without this, readings can be erratic
	adc_select_input(4); // Temperature sensor is analog pin 4
	int v = adc_read();
	adc_set_temp_sensor_enabled(false);
	float t = 27.0f - ((v * _vref / pow(2, _adc_res)) - 0.706f) / 0.001721f; // From the datasheet with custom values for ADC res and Vref voltage
	
	if (type == PAC_F) {
		return t * 1.8f + 32.0f;
	} else {
		return t;
	}
}

float analogVsys()
{
  analogReadResolution(12);
  int vint = analogRead(29);
  
  float v = (((float)vint) * _vref / ((float)pow(2, _adc_res)));
  return v * 3;
}