Arduino

My projects coming soon ...

Follow the Sun

Idea for pointing a solar panel precisely at the sun with three sensors.
Parts designed in Tinkercad printed on Prusa MK4.

Stacks Image 4898787
#include "thingProperties.h"

#define SensorA A3
#define SensorB A4
#define SensorC A5

#define numAverageA 180
#define numAverageB 180
#define numAverageC 180

int valuesA[numAverageA], countAverageA = 0;
int valuesB[numAverageB], countAverageB = 0;
int valuesC[numAverageC], countAverageC = 0;

const int stepPinX = 2;  //2
const int dirPinX = 5;   //5
const int stepPinY = 3;  //3
const int dirPinY = 6;   //6

int valHysteresis = 5;

int speed = 200;

//panMotor = 0;
//tiltMotor = 0;
int actMotor = 100;

bool executed;
unsigned long startzeit = 0;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);
  pinMode(stepPinY, OUTPUT);
  pinMode(dirPinY, OUTPUT);

  pinMode(8, OUTPUT);     // Setze Pin 8 als Ausgang

  //pinMode(SensorA, INPUT);
 // pinMode(SensorB, INPUT);
 // pinMode(SensorC, INPUT);
  
}

void loop() {

  ArduinoCloud.update();

  valueA = analogRead(A3);
  valueB = analogRead(A4);
  valueC = analogRead(A5);

  Serial.println(valueA);

  fvalueA = averageA(valueA);
  fvalueB = averageB(valueB);
  fvalueC = averageC(valueC);

  status = digitalRead(8); 

  //Serial.print("panMotor:");
 Serial.print(panMotor);
 Serial.print(",");

//Serial.print("tiltMotor:");
 Serial.print(tiltMotor);
 Serial.print(",");

 // Serial.print("Max:");
  Serial.print(1023);
  Serial.print(",");

  //Serial.print("Min:");
  Serial.print(0);
  //Serial.print(",");

  //Serial.print("Sensor-A:");
  Serial.print(fvalueA);
  Serial.print(",");

  //Serial.print("Sensor-B:");
  Serial.print(fvalueB);
  Serial.print(",");

  //Serial.print("Sensor-C:");
  Serial.print(fvalueC);
  Serial.print(",");

  //Serial.print("Hysteresis:");
  Serial.println(valHysteresis);
  Serial.println(",");


  // –––––––––– PAN  ––––––––––

  if (abs(fvalueA - fvalueB) > valHysteresis) {

if ((digitalRead(8) == HIGH) && (executed == false)){
  digitalWrite (8, LOW);
  startzeit = millis();
  executed = true;
}

    if (fvalueA > fvalueB) {
      digitalWrite(dirPinX, HIGH); // was HIGH
      panMotor = actMotor;
    } else {
      digitalWrite(dirPinX, LOW); // was LOW
      panMotor = -actMotor;
    }
    digitalWrite(stepPinX, HIGH); // was HIGH
    delayMicroseconds(speed);
    digitalWrite(stepPinX, LOW); // was LOW
    delayMicroseconds(speed);

  }
  
  if (abs(fvalueA - fvalueB) < valHysteresis){
    panMotor = 0;
   if (millis() > startzeit+2000){
    digitalWrite(8, HIGH);
    executed = false;
  }
  }

  // –––––––––– TILT  ––––––––––

  if (abs((fvalueA / 2 + fvalueB / 2) - abs(fvalueC)) > valHysteresis) {

  if ((digitalRead(8) == HIGH) && (executed == false)){
  digitalWrite (8, LOW);
    startzeit = millis();
  executed = true;
}

    if ((fvalueA / 2 + fvalueB / 2) > fvalueC) {
      digitalWrite(dirPinY, HIGH); // was LOW
      tiltMotor = -actMotor;
    } else {
      digitalWrite(dirPinY, LOW); // was HIGH
      tiltMotor = actMotor;
    }
    digitalWrite(stepPinY, LOW); // was HIGH
    delayMicroseconds(speed);
    digitalWrite(stepPinY, HIGH); // was LOW
    delayMicroseconds(speed);    
  }

  if (abs((fvalueA / 2 + fvalueB / 2) - abs(fvalueC)) < valHysteresis) {
  tiltMotor = 5;
 if (millis() > startzeit+2000){
    digitalWrite(8, HIGH);
   Serial.println("Jetzt ist HIGH");
    executed = false;
  }
  }
  
}

// ––––––––––––––––––––––––––––––––––––––––––––––––––––––

float averageA(int newValueA) {
  float averA, sumA = 0;
  valuesA[countAverageA] = newValueA;
  for (int k = 0; k < numAverageA; k++) sumA += valuesA[k];
  averA = (float)sumA / numAverageA;
  countAverageA++;
  if (countAverageA >= numAverageA) countAverageA = 0;
  return averA;
}
float averageB(int newValueB) {
  float averB, sumB = 0;
  valuesB[countAverageB] = newValueB;
  for (int k = 0; k < numAverageB; k++) sumB += valuesB[k];
  averB = (float)sumB / numAverageB;
  countAverageB++;
  if (countAverageB >= numAverageB) countAverageB = 0;
  return averB;
}
float averageC(int newValueC) {
  float averC, sumC = 0;
  valuesC[countAverageC] = newValueC;
  for (int k = 0; k < numAverageC; k++) sumC += valuesC[k];
  averC = (float)sumC / numAverageC;
  countAverageC++;
  if (countAverageC >= numAverageC) countAverageC = 0;
  return averC;
}

// ––––––––––––––––––––––––––––––––––––––––––––––––––––––
// ––––––––––––––––––––––––––––––––––––––––––––––––––––––
// ––––––––––––––––––––––––––––––––––––––––––––––––––––––

// below the things-stuff

// Code generated by Arduino IoT Cloud, DO NOT EDIT.

#include 
#include 

const char SSID[]     = SECRET_SSID;    // Network SSID (name)
const char PASS[]     = SECRET_OPTIONAL_PASS;    // Network password (use for WPA, or use as key for WEP)

int fvalueA;
int fvalueB;
int fvalueC;
int panMotor;
int tiltMotor;
int valueA;
int valueB;
int valueC;
bool status;

void initProperties(){

  ArduinoCloud.addProperty(fvalueA, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(fvalueB, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(fvalueC, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(panMotor, READ, ON_CHANGE, NULL);
  ArduinoCloud.addProperty(tiltMotor, READ, ON_CHANGE, NULL);
  ArduinoCloud.addProperty(valueA, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(valueB, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(valueC, READ, 2 * SECONDS, NULL);
  ArduinoCloud.addProperty(status, READ, ON_CHANGE, NULL);

}

WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);

UV Dosimeter

Determine the exact exposure time in the sun (UV) of cyanotypes.
Based on an idea and some code by Wagner Lungov.

Stacks Image 4898732
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
// –––––––––––––––––––––––––––––––––––––––– UV Dosimeter based on Wagner Lungov ––––––––––––––––––––––––––––––––––––––––
// –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

// –––––––––––––––––––––––––––––––––––––––– Arduino Mega Board 2560 R3 ––––––––––––––––––––––––––––––––––––––––

// rotary encoder  ––– A = PWM6 | B = PWM7 | C = PWM5 | VCC = 3.3 | GND = GND
// uv sensor ML 8511  ––– EN = A0 | OUT = A1 | GND = GND | 3V3 = 3.3V | VIN = empty | EN connected to 3V3
// 1.5inch OLED Module  ––– VCC = 5V | GND = GND | DIN = 51 | CLK = 52| CS = PWM13 | DC = PWM12 | RST = PWM11
// passive buzzer ––– SIGNAL(+) = PWM2 | GND to GND


#include 
U8G2_SSD1327_MIDAS_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/13, /* dc=*/12, /* reset=*/11);

#define outputA 6
#define outputB 7

int counter = 0;
int aState;
int aLastState;
int buttonPin = 5;

boolean isButtonPushDown(void) {
  if (!digitalRead(buttonPin)) {
    delay(30);
    if (!digitalRead(buttonPin))
      return true;
  }
  return false;
}

// –––––––––––––––––––––––––––––––––––––––– variables ––––––––––––––––––––––––––––––––––––––––

int r_sun = 4;
int pgr_bar = 0;
int tm[4];
bool stt = 0;
int uvLevel;
int uvLevel_avg[11];
float uvLevel_cur_avg;
int uvLevel_shift = 200;
float expo;
float expo_so_far;
float expo_left;
long int t_remaining;
float const conv = .003787878;
int pos = 0;
char ckn;
int const k_avg = 3;
long int t_next;
bool pause = 0;
int const buzz = 2;
int const uv_out = A1;
int const uv_ena = A0;
int uv_out_mW = A1;
int uv_ena_mW = A0;  // was A0

// –––––––––––––––––––– my variables ––––––––––––––––––––

int steps = 50;
int uvLevel_alt;
int minuten;
bool flag = false;
long int t_start;
long int t_estimated;
long int t_passed;
int ts[4];
int tc[4];
int te[4];
int maxsun;
int minsun;

int unic;
int dezc;
int cenc;

// –––––––––––––––––––– variables graph ––––––––––––––––––––

const int analogInPin = A1;
int analogInValue = A0;
int x;
int y[128];

int uvLevel_mW;
int refLevel_mW;
int uvIntensity_mW;
int mWcm;
int vltOut;
float outputVoltage_mW;

unsigned char anz = 0;
bool buzzflag = true;
unsigned char i, j;


// –––––––––––––––––––––––––––––––––––––––– setup ––––––––––––––––––––––––––––––––––––––––

void (*resetFunc)(void) = 0; // reset with rotary

void setup() {

  Serial.begin(38400);

  pinMode(outputA, INPUT);
  pinMode(outputB, INPUT);
  pinMode(buttonPin, INPUT);

  aLastState = digitalRead(outputA);

  // –––––––––––––––––––– screen ––––––––––––––––––––

  u8g2.begin();

  u8g2.setFontMode(1);
  u8g2.setDrawColor(1);
  u8g2.setContrast(254);


  expo_so_far = 0;
  pinMode(uv_out, INPUT);
  pinMode(buzz, OUTPUT);
  pinMode(uv_ena, INPUT);
  digitalWrite(uv_ena, HIGH);

  x = 0;     // setup graph
  clearY();  // setup graph

  for (int i = 0; i < k_avg; i++) {
    uvLevel = averageAnalogRead(uv_out) - uvLevel_shift;
    if (uvLevel < 0) uvLevel = 0;
    uvLevel_avg[i] = uvLevel;
    u8g2.firstPage();
  }
  delay(5);
  t_next = millis() + 1000;
  faz_tela();
}

// –––––––––––––––––––––––––––––––––––––––– end setup start loop ––––––––––––––––––––––––––––––––––––––––

void loop() {

  int uvLevel_mW = averageAnalogRead(uv_out_mW);
  int refLevel_mW = averageAnalogRead(uv_ena_mW);
  float outputVoltage_mW = 3.3 / refLevel_mW * uvLevel_mW;
  float uvIntensity_mW = mapfloat(outputVoltage_mW, 0.99, 2.8, 0.0, 15.0);

  mWcm = (uvIntensity_mW * 1000);
  vltOut = (outputVoltage_mW * 1000);

  //------------rotary encoder

  aState = digitalRead(outputA);
  if (aState != aLastState) {
    if (digitalRead(outputB) != aState) {
      counter++;
    } else {
      counter--;
    }
  }
  aLastState = aState;

  if (counter < 0) (counter = 0);

  unic = (counter % 10);
  dezc = ((counter / 10) % 10);
  cenc = ((counter / 100) % 10);

  if (isButtonPushDown()) {
    expo = counter;
    t_start = millis();  // remember starttime (millis) on # key pressed
    if (expo > 0) {
      stt = 1;
      expo_so_far = 0;
    } else {
      delay(0);
    }
  }

  // –––––––––––––––––––– starting timer ––––––––––––––––––––

  if (isButtonPushDown()) {
    expo = counter;
    if (expo > 0) {
      expo_left = expo;
      uvLevel_cur_avg = 0;
      for (int i = 0; i < k_avg; i++) { uvLevel_cur_avg = uvLevel_cur_avg + uvLevel_avg[i]; }
      uvLevel_cur_avg = uvLevel_cur_avg / k_avg;
      t_remaining = round(expo_left / (conv * uvLevel_cur_avg));
      cd_mmss(t_remaining);
      faz_tela();
    } else {
      delay(0);
    }
  }

  if (millis() > t_next) {
    t_next = t_next + 1000;
    uvLevel = averageAnalogRead(uv_out) - uvLevel_shift;
    for (int i = 0; i < k_avg - 1; i++) { uvLevel_avg[i] = uvLevel_avg[i + 1]; }  // shift the last readings
    uvLevel_avg[k_avg - 1] = uvLevel;                                             // add the last
    uvLevel_cur_avg = 0;

    for (int i = 0; i < k_avg; i++) { uvLevel_cur_avg = uvLevel_cur_avg + uvLevel_avg[i]; }
    uvLevel_cur_avg = uvLevel_cur_avg / k_avg;
    if (pause == 0) r_sun = map(uvLevel_cur_avg, 0, 220, 1, 16);
    else r_sun = 1;

    if (stt == 1) {
      if (pause == 0) { expo_so_far = expo_so_far + conv * uvLevel_cur_avg; }
      expo_left = expo - expo_so_far;
      t_remaining = round(expo_left / (conv * uvLevel_cur_avg));
      if (t_remaining < 0) t_remaining = 0;
      cd_mmss(t_remaining);


      t_passed = millis() - t_start;

      cc_mmss((t_estimated - (t_passed / 1000)) - t_remaining);  //  info if faster or slower than expected

      // –––––––––––––––––––– t_estimated, min / max sun remeber ––––––––––––––––––––




      if (flag == false) {
        u8g2.setFont(u8g2_font_freedoomr10_mu);
        t_estimated = t_remaining;
        (maxsun = uvLevel_cur_avg);
        (minsun = maxsun);
        flag = true;
      }

      // Sonne Minimum Maximum set

      u8g2.setFont(u8g2_font_freedoomr10_mu);
      u8g2.setCursor(96, 52);
      u8g2.print(0);
      u8g2.setCursor(96, 66);
      u8g2.print(0);

      // progress bar update

      pgr_bar = map(expo_so_far, 0, expo, 0, 126);
      if (expo_so_far > expo) {
        ce_mmss(t_passed / 1000);
        stt = 0;
        expo_so_far = 0;
        pgr_bar = 0;
        done();
      }
    }
    faz_tela();
  }
}

// –––––––––––––––––––––––––––––––––––––––– end loop start functions ––––––––––––––––––––––––––––––––––––––––

int averageAnalogRead(int pinToRead) {
  byte numberOfReadings = 8;
  unsigned int runningValue = 0;
  for (int x = 0; x < numberOfReadings; x++) runningValue += analogRead(pinToRead);
  runningValue = runningValue / numberOfReadings;
  return (runningValue);
}

void faz_tela() {

  u8g2.firstPage();

  if (mWcm < 0) (mWcm = 0);
  u8g2.setFont(u8g2_font_baby_tf);
  u8g2.setCursor(78, 125);
  u8g2.print(float(mWcm) / 1000);
  u8g2.setCursor(95, 125);
  u8g2.print("mW/cm2");
  //Serial.println(float(vltOut)/1000);

  do {

    u8g2.drawLine(0, 68, 128, 68);
    u8g2.drawLine(0, 127, 128, 127);
    u8g2.drawLine(0, 68, 0, 127);
    u8g2.drawLine(127, 68, 127, 127);

    for (int i = 1; i < 64; 2 * i++) {
      // u8g2.drawPixel(i * 2, 82);
      u8g2.drawPixel(i * 2, 96);
      // u8g2.drawPixel(i * 2, 110);
      u8g2.drawPixel(32, 68 + i * 2);
      u8g2.drawPixel(64, 68 + i * 2);
      u8g2.drawPixel(96, 68 + i * 2);
      u8g2.setDrawColor(0);
      u8g2.drawLine(96, 120, 96, 126);
      u8g2.setDrawColor(1);
    }

    // the line

    analogInValue = analogRead(analogInPin);
    y[x] = map(analogInValue * 2, 0, 1023, 64 - 1, 0);
    x++;
    if (x >= 128) {
      x = 0;
      clearY();
    }
    // end of the line


    drawY();

    //–––––––––––––––––––– arrows ––––––––––––––––––––
    if (t_estimated > t_remaining) u8g2.drawTriangle(73, 60, 79, 53, 67, 53);
    if (t_estimated < t_remaining) u8g2.drawTriangle(73, 42, 80, 50, 66, 50);

    //–––––––––––––––––––– progress bar ––––––––––––––––––––

    if (t_remaining < t_estimated) {

      u8g2.drawLine(99, 64, 99, (t_remaining * 64 / t_estimated));
      u8g2.drawLine(100, 64, 100, (t_remaining * 64 / t_estimated));
      u8g2.drawLine(101, 64, 101, (t_remaining * 64 / t_estimated));
    }

    // –––––––––––––––––– bar graph + uv level––––––––––––––––––––––

    if (uvLevel_cur_avg > 4 * steps) {
      u8g2.drawBox(107, 11, 20, 9);
    }
    if (uvLevel_cur_avg > 3 * steps) {
      u8g2.drawBox(107, 22, 20, 9);
    }
    if (uvLevel_cur_avg > 2 * steps) {
      u8g2.drawBox(107, 33, 20, 9);
    }
    if (uvLevel_cur_avg > steps) {
      u8g2.drawBox(107, 44, 20, 9);
    }
    if (uvLevel_cur_avg > 1) {
      u8g2.drawBox(107, 55, 20, 9);
    }
    if (uvLevel_cur_avg < 10) u8g2.setCursor(120, 12);
    if (uvLevel_cur_avg > 9) u8g2.setCursor(112, 12);
    if (uvLevel_cur_avg > 99) u8g2.setCursor(104, 12);

    u8g2.setFont(u8g2_font_freedoomr10_mu);
    u8g2.print(round(uvLevel_cur_avg));
    uvLevel_alt = (round(uvLevel_cur_avg));

    //

    minuten = tm[0];

    u8g2.setFont(u8g2_font_freedoomr25_mn);
    if (minuten < 9) {
      u8g2.setCursor(0, 26);
      u8g2.print(tm[0]);
      u8g2.setCursor(23, 26);
      u8g2.print(tm[1]);
      //u8g2.setCursor(41, 22); u8g2.print(':');
      u8g2.drawBox(47, 7, 3, 5);
      u8g2.drawBox(47, 17, 3, 5);
      u8g2.setCursor(54, 26);
      u8g2.print(tm[2]);
      u8g2.setCursor(77, 26);
      u8g2.print(tm[3]);
    }
    if (minuten > 9) {
      u8g2.setCursor(0, 26);
      u8g2.print('-');
      u8g2.setCursor(23, 26);
      u8g2.print('-');
      //u8g2.setCursor(41, 26); u8g2.print(':');
      u8g2.drawBox(47, 7, 3, 5);
      u8g2.drawBox(47, 17, 3, 5);
      u8g2.setCursor(54, 26);
      u8g2.print('-');
      u8g2.setCursor(77, 26);
      u8g2.print('-');
    }

    u8g2.setFont(u8g2_font_freedoomr25_mn);
    u8g2.setCursor(0, 66);
    u8g2.print(cenc);
    u8g2.setCursor(22, 66);
    u8g2.print(dezc);
    u8g2.setCursor(44, 66);
    u8g2.print(unic);
    // u8g2.drawLine(pos * 22, 65, pos * 22 + 18, 65);
    // u8g2.drawLine(pos * 22, 64, pos * 22 + 18, 64);

    u8g2.setFont(u8g2_font_freedoomr10_mu);
    if (t_estimated == t_remaining) {
      u8g2.setCursor(2, 39);
      u8g2.print(tm[0]);
      u8g2.setCursor(10, 39);
      u8g2.print(tm[1]);
      u8g2.setCursor(18, 39);
      u8g2.print(':');
      u8g2.setCursor(26, 39);
      u8g2.print(tm[2]);
      u8g2.setCursor(34, 39);
      u8g2.print(tm[3]);
      ts[0] = tm[0];
      ts[1] = tm[1];
      ts[2] = tm[2];
      ts[3] = tm[3];
    } else {
      u8g2.setCursor(2, 39);
      u8g2.print(ts[0]);
      u8g2.setCursor(10, 39);
      u8g2.print(ts[1]);
      u8g2.setCursor(18, 39);
      u8g2.print(':');
      u8g2.setCursor(26, 39);
      u8g2.print(ts[2]);
      u8g2.setCursor(34, 39);
      u8g2.print(ts[3]);
    }

    // show ecent correctio + sun min an max

    if (flag == true) {
      if (t_estimated > t_remaining) {
        u8g2.setCursor(46, 39);
        u8g2.print('-');
      }
      if (t_estimated < t_remaining) {
        u8g2.setCursor(46, 39);
        u8g2.print('+');
      }
      u8g2.setCursor(56, 39);
      u8g2.print(abs(tc[0]));
      u8g2.setCursor(64, 39);
      u8g2.print(abs(tc[1]));
      u8g2.setCursor(72, 39);
      u8g2.print(':');
      u8g2.setCursor(80, 39);
      u8g2.print(abs(tc[2]));
      u8g2.setCursor(88, 39);
      u8g2.print(abs(tc[3]));


      if (uvLevel_cur_avg > maxsun) (maxsun = uvLevel_cur_avg);
      if (maxsun < 10) u8g2.setCursor(88, 52);
      if (maxsun > 9) u8g2.setCursor(80, 52);
      if (maxsun > 99) u8g2.setCursor(72, 52);
      u8g2.print(round(maxsun));

      if (uvLevel_cur_avg < minsun) (minsun = uvLevel_cur_avg);
      if (minsun < 10) u8g2.setCursor(88, 66);
      if (minsun > 9) u8g2.setCursor(80, 66);
      if (minsun > 99) u8g2.setCursor(72, 66);
      u8g2.print(round(minsun));
    }

    if (flag == false) {
      u8g2.setCursor(56, 39);
      u8g2.print(abs(te[0]));
      u8g2.setCursor(64, 39);
      u8g2.print(abs(te[1]));
      u8g2.setCursor(72, 39);
      u8g2.print(':');
      u8g2.setCursor(80, 39);
      u8g2.print(abs(te[2]));
      u8g2.setCursor(88, 39);
      u8g2.print(abs(te[3]));

      if (flag == false) {
        if (maxsun < 10) u8g2.setCursor(88, 52);
        if (maxsun > 9) u8g2.setCursor(80, 52);
        if (maxsun > 99) u8g2.setCursor(72, 52);
        u8g2.print(round(maxsun));
        if (minsun < 10) u8g2.setCursor(88, 66);
        if (minsun > 9) u8g2.setCursor(80, 66);
        if (minsun > 99) u8g2.setCursor(72, 66);
        u8g2.print(round(minsun));
      }
    }
  } while (u8g2.nextPage());

  if (isButtonPushDown()) {
    if (counter == 0) {  // reset procedure
      resetFunc();
    }
  }
}

// –––––––––––––––––––––––––––––––––––––––– functions ––––––––––––––––––––––––––––––––––––––––

void cd_mmss(float t) {  // time remaining
  tm[0] = t / 600;
  tm[1] = (t - tm[0] * 600) / 60;
  tm[2] = (t - tm[0] * 600 - tm[1] * 60) / 10;
  tm[3] = (t - tm[0] * 600 - tm[1] * 60 - tm[2] * 10);
}

void cc_mmss(float t)  // time deviation
{
  tc[0] = t / 600;
  tc[1] = (t - tc[0] * 600) / 60;
  tc[2] = (t - tc[0] * 600 - tc[1] * 60) / 10;
  tc[3] = (t - tc[0] * 600 - tc[1] * 60 - tc[2] * 10);
}

void ce_mmss(float t)  // time used
{
  te[0] = t / 600;
  te[1] = (t - te[0] * 600) / 60;
  te[2] = (t - te[0] * 600 - te[1] * 60) / 10;
  te[3] = (t - te[0] * 600 - te[1] * 60 - te[2] * 10);
}

void done(void) {

  // digitalWrite(buzz, HIGH);
  // delay(100);
  // digitalWrite(buzz, LOW);
  // delay(100);
  // digitalWrite(buzz, HIGH);
  // delay(300);
  // digitalWrite(buzz, LOW);
  // delay(100);
  // digitalWrite(buzz, HIGH);
  // delay(100);
  // digitalWrite(buzz, LOW);
  // delay(600);

  // –––––––––– passive buzzer ––––––––––

  if (buzzflag == true) {
    for (anz = 1; anz < 4; anz++) {
      for (i = 0; i < 120; i++) {
        digitalWrite(buzz, HIGH);
        delay(1);
        digitalWrite(buzz, LOW);
        delay(2);
      }
      for (i = 0; i < 160; i++) {
        digitalWrite(buzz, HIGH);
        delay(1);
        digitalWrite(buzz, LOW);
        delay(1);
      }
      buzzflag = false;
    }
  }

  flag = false;
}

void clearY() {
  for (int i = 0; i < 128; i++) {
    y[i] = -1;
  }
}

void drawY() {
  for (int i = 1; i < 128; i++) {
    if (y[i] != -1) {
      //u8g2.drawPixel(i, y[i]);
      u8g2.drawLine(i - 1, y[i - 1] * 2 + 44, i, y[i] * 2 + 44);
    } else {
      break;
    }
  }
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

©2025 Hardy Hemmi | mail@hardyhemmi.ch

Arduino | Hardy Hemmi