dobrý den, stále se pokouším rozlousknout , jak správně zobrazit v Mode6 výpis, který nebude ovlivňovat rychlost vrtění serva.kiRRow mi dal nápovědy, ale jak dělám co dělám
V kodu jsem přidal výpis v mode6 odpočet v sekundách, ano tam jde krásně vidět jako by rozdíl času. A když už jsem byl u toho zkoumání, přidal jsem mode7, které po stisknutí tlačítka Start rozvrtí servo a vrtí a vrtí do doby než stisknu tlačítko Stop. Výpis je taky na lcd, když servo je v Mode 7 - STOP, tak výpis zobrazuje servo III., a při Mode 7 - START, pak výpis servo auto. Snad mi poradíte , jak to dokončit.
Kód: Vybrat vše
#define buttonSelectUp 2 // číslo pinu tlačítka SELECT pro výběr MODE nahoru
#define buttonStart 3 // číslo pinu tlačítka START/STOP - červené
#define buttonSelectDown 4 // číslo pinu tlačítka pro výběr MODE dolů
#define LED1 10 // číslo pinu LED1 zelená
#define LED2 11 // číslo pinu LED2 červená
#define LED3 5
#define LED4 6
#include <Wire.h> // knihovny pro LCD přes I2C
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // nastavení adresy I2C (0x27), počtu znaků, řádků LCD 20x4
#include <Servo.h> // knihovna pro ovládání serva
Servo myservo; // instance třídy servo viz. Objektově Orientované Programování
int pos = 0; // proměnná úhlu natočení serva
int step = 0; // ukládá se do ní hodnotu jednoho kroku serva
int poc = 0;
boolean buttonStateUp = false; // nejnovější hodnota načtená ze vstupního pinu
boolean lastButtonStateUp = false; // předchozí hodnota načtení ze vstupního pinu
boolean lastTrueButtonStateUp = false; // předchozí hodnota ošetřeného tlačítka
boolean buttonStateStart = false;
boolean lastButtonStart = false;
boolean lastTrueButtonStart = false;
boolean buttonStateDown = false;
boolean lastButtonStateDown = false;
boolean lastTrueButtonStateDown = false;
int mode = 0;
boolean mamBezet = false;
unsigned long lastDebounceTime = 0; // čas posledního změny výstupního pinu
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay = 50; // čas debounce prodlevy
unsigned long aktualniMillis; //aktualní čas
unsigned long predchoziMillis1; // předchozí čas pro rychle blikání
unsigned long predchoziMillis2; // předchozí čas pro pomalé blikání
unsigned long predchoziMillis3; // předchozí čas pro střídavé blikání
unsigned long casCekani; // proměnná - do ní bude uložen čas, který už program načekal od stisku tlačítka start
unsigned long casVrteni; // proměnná - do ní bude uložen čas, který program vrtěl servem od stisknutí tlačítka start
unsigned long blokujLCD;
byte casNaDisplej = 0;
byte prepocitanyCas;
byte casJakDlouhoJestePobezim;
long buttonTime; // čas začátku stisknutí tlačítka
boolean led1svetlo; // pomocná proměnná led1svetlo
boolean led2svetlo; // pomocná proměnná led2svetlo
boolean vypisLCD = true; // proměnná kde si uchovávám jestli je potřeba provést update na lcd displeji
boolean vypisLinku = true;
void setup() {
pinMode(LED1, OUTPUT); // pin pro LED1 nastaven jako výstup
pinMode(LED2, OUTPUT); // pin pro LED2 nastaven jako výstup
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(buttonSelectUp, INPUT); // pin pro tlačítko buttonSelect nastaveno jako vstup
pinMode(buttonStart, INPUT); // pin pro tlačítko buttonStart nastaveno jako vstup
pinMode(buttonSelectDown, INPUT); //pin pro tlačítko buttonSelectDown nastaveno jako vstup
myservo.attach(9); // pin pro servo
lcd.begin(); // inicializace LCD
lcd.backlight(); // zapnutí podsvícení
Serial.begin(9600); // konfigurace rychlosti seriového portu
Serial.println("Seriovy port aktivni"); // První výpis na seriový port
lcd.setCursor( 2, 1);
lcd.print("ready");
delay(1500);
}
void loop(){
//-------------- debounce pro tlačítko Select Up ----------
buttonStateUp = digitalRead(buttonSelectUp); // přečtení stavu tlačítka
if (buttonStateUp != lastButtonStateUp) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) { // jo, uz se to dlouho nezmenilo, tak je to stabilni a spravna hodnota
if (buttonStateUp != lastTrueButtonStateUp) { // Pokud se stav tlačítka změnil tj. porovná se buttonState (stav tlačítka) s předchozím stavem
if(buttonStateUp == true) {
// přidáním podmínky - začátek počítání vždy např. od 10s
if(mamBezet == false) { // a taky přepnutí mode jen tehdy, když jsou mode ve Stop
if(mode < 7) { // když je hodnota mode menší než 7
mode++; // přičte k mode hodnotu 1
vypisLCD = true;
}
}
}
lastTrueButtonStateUp = buttonStateUp; // uložím si nový pravý ošetřený stav tlačítka
}
}
lastButtonStateUp = buttonStateUp; // tady si to ulozim, v dalsim pruchodu loop() to zase porovnam s novym stavem, zda se to mezi tim nezmenilo
//---------------konec ošetření tlačítka Select Up -----------
//-------------- debounce pro tlačítko Select Down ----------
buttonStateDown = digitalRead(buttonSelectDown); // přečtení stavu tlačítka
if (buttonStateDown != lastButtonStateDown) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
lastDebounceTime3 = millis();
}
if ((millis() - lastDebounceTime3) > debounceDelay) { // jo, uz se to dlouho nezmenilo, tak je to stabilni a spravna hodnota
if (buttonStateDown != lastTrueButtonStateDown) { // Pokud se stav tlačítka změnil tj. porovná se buttonState (stav tlačítka) s předchozím stavem
if(buttonStateDown == true) {
// přidáním podmínky docílím vždy celého odpočtu času 10s !
if(mamBezet == false) { // a taky přepnutí mode jen tehdy, když jsou mode ve Stop
if(mode > 0) { // když je mode větší než 0
mode--; // odečte od mode hodnotu 1
vypisLCD = true;
}
}
}
lastTrueButtonStateDown = buttonStateDown; // uložím si nový pravý ošetřený stav tlačítka
}
}
lastButtonStateDown = buttonStateDown; // tady si to ulozim, v dalsim pruchodu loop() to zase porovnam s novym stavem, zda se to mezi tim nezmenilo
//-------------- konec ořetření tlačítka Select Down ----------
//-------------- debounce pro tlačítko START/STOP ----------
buttonStateStart = digitalRead(buttonStart); // přečtení stavu tlačítka
if (buttonStateStart != lastButtonStart) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay) { // jo, uz se to dlouho nezmenilo, tak je to stabilni a spravna hodnota
if (buttonStateStart != lastTrueButtonStart) { // Pokud se stav tlačítka změnil tj. porovná se buttonState (stav tlačítka) s předchozím stavem
if (buttonStateStart == true) {
mamBezet = !mamBezet;
buttonTime = millis();
vypisLCD = true; // příkaz vypisuje funkci tlačítka, tedy start / stop
Serial.println("stisk START/STOP"); // výpis na seriový monitor stisknutí tlačítka START/STOP
}
// TADY CHYBÍ CO SE MÁ PROVÉST PŘI STISKU TLAČÍTKA START ... U MODE SE PŘIČÍTÁ MODE ...
// ...U STARTU BY SE MĚLA PŘEKLÁPĚT PROMĚNNÁ mamBezet - hoď si tu nějaký výpis do seriové linky a uvidíš že to funguje
}
lastTrueButtonStart = buttonStateStart; // uložím si nový pravý ošetřený stav tlačítka
}
lastButtonStart = buttonStateStart; // tady si to ulozim, v dalsim pruchodu loop() to zase porovnam s novym stavem, zda se to mezi tim nezmenilo
//-------------- konec ořetření tlačítka Start/Stop ----------
if(mode == 0) { // ******* LED1,LED2 vypnuto ********
if(mamBezet == false){
led1svetlo = false; // zhasni LED1
led2svetlo = false; // zhasni LED2
}
}
if(mode == 1) { // ******* LED1,LED2 zapnuto ********
if(mamBezet == true){
led1svetlo = true;
led2svetlo = true;
} else {
led1svetlo = false;
led2svetlo = false;
}
}
if(mode == 2) { // ******* LED1,LED2 blikání rychlé *******
if(mamBezet == true) { // program spuštěn
casCekani = millis() - buttonTime; //musíš si definovat novou proměnnou - do ní bude uložen čas který už program načekal od stisku tlačítka start
if(casCekani > 10000){ // zjistím si jestli je čas něco provést, uběhlo už 10s od poslední akce?
vypisLCD = true; // cekani uběhlo, potřebuji vypsat displej (akorát ho to bude vypisovat pokaždé, když to teď poběží kolem)
// dá se to vyřešit tak, že si vytvořím další proměnnou blokujLCD ... a po prvním výpisu si ji nastavím na true - a vypis obalím do podmínky
if(blokujLCD == false) { vypisLCD = true; blokujLCD = true; }
aktualniMillis = millis(); // podívám se na hodinky - aktuální čas
if(aktualniMillis - predchoziMillis1 > 200) { // nejprve si zjistím jestli je čas něco provést, uběhlo už 200ms od poslední akce?
if (led1svetlo) {
led1svetlo = false; // zhasnu LED1
led2svetlo = false; // zhasnu LED2
} else {
led1svetlo = true; // rožnu LED1
led2svetlo = true; // rožnu LED2
}
predchoziMillis1 = aktualniMillis; // v tento čas jsem provedl poslední akci
}
} else {
led1svetlo = false;
led2svetlo = false;
vypisLCD = true;
blokujLCD = true; // program skoncil, takže si uvolním blokaci displeje blokujLCD = false
}
}
}
if(mode == 3) { // ******* LED1,LED2 blikání pomalé *******
if(mamBezet == true){
aktualniMillis = millis(); //podívám se na hodinky - aktuální čas
if(aktualniMillis - predchoziMillis2 > 500) { // nejprve si zjistím jestli je čas něco provést, uběhlo už 500ms od poslední akce?
if (led2svetlo) {
led1svetlo = false; // zhasnu LED1
led2svetlo = false; // zhasnu LED2
} else {
led1svetlo = true; // rožnu LED1
led2svetlo = true; // rožnu LED2
}
predchoziMillis2 = aktualniMillis; // v tento čas jsem provedl poslední akci
}
} else {
led1svetlo = false;
led2svetlo = false;
}
}
if(mode == 4) { // ******* LED1,LED2 blikání střídavé *******
if(mamBezet == true){
aktualniMillis = millis(); //podívám se na hodinky - aktuální čas
if(aktualniMillis - predchoziMillis3 > 300) { // nejprve si zjistím jestli je čas něco provést, uběhlo už 300ms ?
led1svetlo = !led1svetlo; // do proměnné led1svetlo zapíšu její negovanou hodnotu, tj. svítila-li LED1 tak zhasne, byla-li zhaslá rožne se
led2svetlo = !led1svetlo; // do proměnné led2svetlo zapíšu negovanou hodnotu led1svetlo, tj. pokud LED1 svítí chci LED2 zhaslou a naopak
predchoziMillis3 = aktualniMillis; // v tento čas jsem provedl poslední akci
}
} else {
led1svetlo = false;
led2svetlo = false;
}
}
if(mode == 5){ // ********** SERVO I. **********
if(mamBezet == true) { // program spuštěn
if(lastTrueButtonStateUp == true){ // stisknuto tlačítko selectUp
//pokud můžu a nebourám servem do krajní pozice, měním pozici serva
if(pos <= 175){
pos +=1;
myservo.write(pos);
}
}
if(lastTrueButtonStateDown == true){ // stisknuto tlačítko selectDown
//pokud můžu a nebourám servem do druhé krajní pozice, měním pozici serva druhým směrem
if(pos >= 5){
pos -=1;
myservo.write(pos);
}
}
digitalWrite(LED4, pos < 175); // LED4 svítí, když je servo v pozici Up - 175° stupňů
digitalWrite(LED3, pos > 5); // LED3 svítí, když je servo v pozici Down - 5° stupňů
}
}
if(mamBezet == false){ // když je mode5 ve stavu Stop, tak ledky jsou zhasnuté
digitalWrite(LED4,false);
digitalWrite(LED3,false);
}
if(mode == 6) { // ******* SERVO II. VRTÍ se 15s ********
if(mamBezet == true){ // program spuštěn
casVrteni = millis() - buttonTime;
vypisLCD = true; // POKUD JE vypisLCD ODKOMENTOVANÝ VRTÍ SE SERVO VELMI POMALU - PROČ ???
if(casVrteni <= 15000) { // podmínka pro čas vrtění serva
if (pos <= 0) { // zkontroluji si jestli je pozice 0 nebo méně
step = 1; // nastavím step na 1 (TOHLE JE ZMĚNA SMĚRU
}
if (pos >= 180) { // zkontroluji si jestli je pozice 180 nebo více
step = -1; // nastavím step na -1 (TOHLE JE ZMĚNA SMĚRU)
}
pos += step; // k pozici motoru přičtu step (TA JE BUĎ 1 A POS SE ZVYŠUJE, NEBO -1 A POS SE SNIŽUJE)
digitalWrite(LED4,pos>=175);
digitalWrite(LED3,pos<=5);
myservo.write(pos); // nastavení serva na pozici
delay(7); // nějaký ten delay, aby se to stihlo natočit
}
}
}
if(mode == 7){ // ******* SERVO III. AUTO *******
if(mamBezet == true) { // program spuštěn
if (pos <= 0) { // zkontroluji si jestli je pozice 0 nebo méně
step = 1; // nastavím step na 1 (TOHLE JE ZMĚNA SMĚRU
}
if (pos >= 180) { // zkontroluji si jestli je pozice 180 nebo více
step = -1; // nastavím step na -1 (TOHLE JE ZMĚNA SMĚRU)
}
pos += step; // k pozici motoru přičtu step (TA JE BUĎ 1 A POS SE ZVYŠUJE, NEBO -1 A POS SE SNIŽUJE)
digitalWrite(LED4,pos>=175);
digitalWrite(LED3,pos<=5);
myservo.write(pos); // nastavení serva na pozici
delay(7); // nějaký ten delay, aby se to stihlo natočit
}
}
digitalWrite(LED1,led1svetlo); // aktualizace stavu LED1, zápis proměnné led1svetlo na výstupní pin 10
digitalWrite(LED2,led2svetlo); // aktualizace stavu LED2, zápis proměnné led2svetlo na výstupní pin 11
/*OBSLUHA 20x4 LCD DISPLAY*/
if(vypisLCD){
lcd.setCursor( 0, 1); // tady se zadává pozice výpisu 3 znak, 2 řádek
lcd.print(" Mode ");
lcd.print(mode);
lcd.print(" - ");
if(mamBezet){
lcd.print("START");
} else {
lcd.print("STOP ");
}
if(mode == 1){
lcd.setCursor( 2, 2);
lcd.print(" "); // vymazání výpisu ...koment mode
}
if(mode == 2){ // Dle mode vyberu který
if(mamBezet == true){ // bezi a bud ceka nebo neceka
if(casCekani < 10000){ // bezi a ceka ... vypisuji informaci o cekani ... napr zbyva 10000 - casCekani
lcd.setCursor( 2, 2);
lcd.print(10000 - casCekani);
// lcd.setCursor( 6, 2);
lcd.print(" ms ");
}else{ // beží a nečeká ... vypisuje informaci ... ledky blikají
lcd.setCursor( 2, 2);
lcd.print("ledky blikaji");
vypisLCD = true;
}
}else{ // nebezí ... vypisuje informaci ... co se děje v mode
lcd.setCursor( 2, 2);
lcd.print("s cekanim ");
}
}
if(mode == 3){
lcd.setCursor( 2, 2);
lcd.print("500 ms "); // výpis v mode blikání led 500 ms
}
if(mode == 4){
lcd.setCursor( 2, 2);
lcd.print("300 ms "); // výpis v mode blikání led 300 ms
}
if(mode == 5){
lcd.setCursor( 2, 3);
lcd.print(" ");
lcd.setCursor( 2, 2);
lcd.print("servo I. "); // výpis, že mode obsluhuje servo
if(mamBezet == true) { // program spuštěn
lcd.setCursor( 2, 2);
lcd.print("servo manual");
}
}
//**************************** MODE 6 VÝPISY ***** UPRAVIT !!! *****************
/*
byte casNaDisplej = 0; // schválně si tam dám 0, protože první výpočet nebude 0 a hned se mi vypíše - viz níže
// potom nekde dále v mode 6, kdy vypocitavas cas jak dlouho to jeste pojede
// si ten vypocteny cas musis prevest na vteriny, zaokrouhlit ho na cele cislo
// a porovnat s tím co zobrazujes na displeji
byte prepocitanyCas = casJakDlouhoJestePobezim / 1000; // do byte se prostě 9.998 nevleze a ulozi se jen 9 - ale na konci zase bude ukazovat 0s :D
if(casNaDisplej != prepocitanyCas){ // vypocetl jsem ze ty casy se neshoduji, je tedy treba vypsat novy cas na displej
casNaDisplej = prepocitanyCas; // zaktualizuji si promennou kterou vypisuji na displej
vypisLCD = true; // a necham na konci loopu vypsat displej
}
*/
if(mode == 6){
if(mamBezet == true){ // program spuštěn
if(casVrteni < 15000){
lcd.setCursor( 2, 2);
// lcd.print(casVrteni); // vypisuje čas vrtění serva od 0 ms do 15000 ms
lcd.print(15000 - casVrteni); // vypisuje > odečet < času vrtění serva od 15000 ms do 0 ms
lcd.print(" ms ");
prepocitanyCas = 15000 - casVrteni;
casJakDlouhoJestePobezim = (15 - casVrteni / 1000);
lcd.setCursor( 2, 3);
lcd.print(casJakDlouhoJestePobezim);
lcd.print(" s ");
byte casNaDisplej = 0;
byte prepocitanyCas = casJakDlouhoJestePobezim;
if(casNaDisplej != prepocitanyCas){
casNaDisplej = prepocitanyCas;
vypisLCD = true;
}
}else{
lcd.setCursor( 2, 2); // pozice kursoru
lcd.print("servo pauza"); // výpis na lcd
}
} else{
lcd.setCursor( 2, 2);
lcd.print("servo II. ");
}
}
if(mode == 7){
lcd.setCursor( 2, 3);
lcd.print(" ");
lcd.setCursor( 2, 2);
lcd.print("servo III. ");
if(mamBezet == true) { // program spuštěn
lcd.setCursor( 2, 2);
lcd.print("servo auto ");
}
}
//******************************************************************************
vypisLCD = false;
}
/*KONEC OBSLUHY 20x4 LCD DISPLAY*/
}
a tady přidávám video, kde je ukázaná část se servem - rychlosti vrtění, výpisy ...