#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte flaga=0;
uint16_t tz;
uint32_t ttz;
uint64_t ltz1=0;
uint64_t ltz2=0;
unsigned long timestamp;
char bufor[20];
char bufor2[20];
float prad;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] =
{{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}};
byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6, 5};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
enum menus {MAIN, IMPULS_TIME, FREQ, FREQ_MIN} activeMenu = MAIN;
enum sterringModes {POTENTIOMETERS, KEYPAD} activeMode = POTENTIOMETERS;
String number = "";
void setup() {
lcd.begin(20, 4);
Serial.begin(9600);
timestamp = millis();
analogReference(DEFAULT);
pinMode(2, OUTPUT); //sygnał zapłonu kanał 1
pinMode(3, OUTPUT); //sygnał zapłonu kanał 2
pinMode(4, OUTPUT); //buzzer
}
void loop() {
prad = 50.0 * analogRead(A2) / 1023.0;
prad = constrain(prad, 0, 20);
if (millis() % 100 == 0 && activeMode == POTENTIOMETERS){
tz = 1000 + 9000 * uint32_t(analogRead(A0))/1023;
ttz = 400000 - tz - 395000*uint32_t(analogRead(A1))/1023;
if ((tz + 100) >= ttz){
ttz = tz - 100;
}
}
ltz1=impuls(ltz1, tz, ttz, 0, 2);
if (micros() - ltz1 < 10){
if (bitRead(flaga, 0) == 1){
ltz2 = ltz1 + (uint32_t(tz) + ttz) / 2;
}
}
ltz2 = impuls(ltz2,tz,ttz,1,3);
showLcd();
keypadHandlig();
}
uint32_t impuls(uint32_t t1, uint32_t t2, uint32_t t3, byte f_nr, byte D_nr) {
if (micros()>=t1){
if (bitRead(flaga,f_nr)==0){
digitalWrite(D_nr,HIGH);
t1=t1+t2;
bitSet(flaga,f_nr);
}else{
digitalWrite(D_nr,LOW);
t1=t1+t3;
bitClear(flaga,f_nr);
}
}
return t1;
}
void showLcd(){
if(millis() - timestamp > 500){
timestamp = millis();
lcd.clear();
switch(activeMenu){
case MAIN: showMainMenu(); break;
case IMPULS_TIME: showImpulsTimeMenu(); break;
case FREQ: showFreqMenu(); break;
case FREQ_MIN: showFreqMinMenu(); break;
}
}
}
void showMainMenu(){
// lcd.setCursor(0, 0);
// sprintf(bufor, "tz: %d", tz);
// lcd.print(bufor);
// lcd.setCursor(0, 1);
// sprintf(bufor, "ttz: %ld", ttz);
// lcd.print(bufor);
/////////////////////////////////
lcd.setCursor(0, 0);
dtostrf(getImpulsTimeMs(), 5, 2, bufor2);
sprintf(bufor, "Czas impulsu:%sms", bufor2);
lcd.print(bufor);
lcd.setCursor(0, 1);
sprintf(bufor, "Czestotliwosc: %dHz", getFreq());
lcd.print(bufor);
lcd.setCursor(0, 2);
sprintf(bufor, "(%05d zaplonow/min)", getFreq()*60);
lcd.print(bufor);
lcd.setCursor(0, 3);
dtostrf(prad, 5, 2, bufor2);
sprintf(bufor, "Prad cewki: %sA", bufor2);
lcd.print(bufor);
}
void showImpulsTimeMenu(){
lcd.setCursor(0, 0);
lcd.print("Czas impulsu");
lcd.setCursor(0, 1);
dtostrf(getImpulsTimeMs(), 5, 2, bufor2);
sprintf(bufor, "Akt: %sms", bufor2);
lcd.print(bufor);
lcd.setCursor(0, 2);
lcd.print("Nowa: ");
lcd.print(number.toInt());
}
void showFreqMenu(){
lcd.setCursor(0, 0);
lcd.print("Czestotliwosc");
lcd.setCursor(0, 1);
sprintf(bufor, "Akt: %02dHz", getFreq());
lcd.print(bufor);
lcd.setCursor(0, 2);
lcd.print("Nowa: ");
lcd.print(number.toInt());
}
void showFreqMinMenu(){
lcd.setCursor(0, 0);
lcd.print("zaplonow/min");
lcd.setCursor(0, 1);
sprintf(bufor, "Akt: %05d", getFreq()*60);
lcd.print(bufor);
lcd.setCursor(0, 2);
lcd.print("Nowa: ");
lcd.print(number.toInt());
}
void buzz(){
digitalWrite(4, HIGH);
delay(100);
digitalWrite(4, LOW);
}
void setMenu(menus newMenu){
activeMenu = newMenu;
number = "";
}
bool validValues(){
int numInt = number.toInt();
if(activeMenu == IMPULS_TIME && numInt >= 100 && numInt <= 1000) return true;
else if(activeMenu == FREQ && numInt >= 1 && numInt <= 100) return true;
else if(activeMenu == FREQ_MIN && numInt >= 60 && numInt <= 6000) return true;
return false;
}
void keypadHandlig(){
char key = keypad.getKey();
if(key != NO_KEY){
buzz();
if(key == '*' && activeMenu == MAIN){
activeMode = activeMode == POTENTIOMETERS ? KEYPAD : POTENTIOMETERS;
return;
}
if(activeMode == KEYPAD){
if(key == 'A') setMenu(IMPULS_TIME);
else if(key == 'B') setMenu(FREQ);
else if(key == 'C') setMenu(FREQ_MIN);
else if(key == 'D') setMenu(MAIN);
else if(key >= '0' && key <= '9' && activeMenu != MAIN){
number += key;
}
else if(key == '#' && number.toInt() > 0){
if(validValues()){
setNewValuesTzTtz();
setMenu(MAIN);
}
else{
setMenu(activeMenu);
}
}
}
}
}
float getImpulsTimeMs(){
return tz / 1000.0;
}
int getFreq(){
uint64_t f = 1000000 / (tz + ttz);
return f;
}
void setNewValuesTzTtz(){
//przeliczenie dla tz
//100 tj. 1ms -> 1000us
//1000 tj. 10ms -> 10000us
if(activeMenu == IMPULS_TIME){
setNewTz(number.toInt() * 10); //przeliczenie na us
}
else if(activeMenu == FREQ){
setNewFreq(number.toInt());
}
else if(activeMenu == FREQ_MIN){
setNewFreq(number.toInt() / 60.0);
}
}
void setNewTz(float newTz){
float T = tz + ttz; //okres
tz = newTz; //nowa wartość tz
ttz = T - tz; //ttz wynika z różnicy
}
void setNewFreq(float newF){
float T = tz + ttz;
float wypelnienie = tz / T;
uint32_t newT = 1000000 / newF;
//Serial.println("##########################################");
// showSerial(T, tz, ttz, getFreq(), wypelnienie*100);
tz = wypelnienie * newT;
ttz = newT - tz;
// showSerial(newT, tz, ttz, newF, wypelnienie*100);
}
void showSerial(float T, float tz, float ttz, float f, float wyp){
Serial.print("T\t"); Serial.print(T); Serial.println(" us");
Serial.print("tz\t"); Serial.print(tz); Serial.println(" us");
Serial.print("ttz\t"); Serial.print(ttz); Serial.println(" us");
Serial.print("f\t"); Serial.print(f); Serial.println(" Hz");
Serial.print("wyp\t"); Serial.print(wyp); Serial.println(" %");
}