Idea for pointing a solar panel precisely at the sun with three sensors.
Parts designed in Tinkercad printed on Prusa MK4.
#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);
Determine the exact exposure time in the sun (UV) of cyanotypes.
Based on an idea and some code by Wagner Lungov.
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
// –––––––––––––––––––––––––––––––––––––––– 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;
}