Skocz do zawartości

Logiczne 0 pętli do while


Gal_kris

Pomocna odpowiedź

last =0;
do{
if(last!=now) Serial.print("działa");
  last = now;
}while(1);

Witam wszystkich.

Badam sobie tą pętlę i zauważyłem że po pierwszym spełnieniu warunku pętla ma wartość 1 a po drugim wartość 0. Szukam po internecie informacji czy istnieje możliwość by pętla zawsze kończyła z logicznym 0

Krysrian

  • Lubię! 1
Link do komentarza
Share on other sites

Pętla ma wartość? Wartość to mogą mieś zmienne, stałe, a nie pętla która jest ciągiem powtarzalnych instrukcji. Spróbuj bardziej precyzyjnie zadać swoje pytanie. Podajesz fragment programu ale z tego nie wynika czym jest last, a tym bardziej czym jest now.

Wypowiadaj się bardziej precyzyjnie.

Link do komentarza
Share on other sites

Last to ostatni odczyt i jest zmienną

now to nowy odczyt i też jest zmienną

po wejściu do pętli wartość last i Now ma 0.

po spełnieniu warunku czyli Now dostaje 1 pętla rusza i last dostaje 1.

mam teraz dwie jedynki, zmieniam wartość Now na 0, znów pętla rusza i teraz mam dwa razy 0.

pytanie czy można tak zrobić by zawsze po wykonaniu pętli wartości last i now miały 0

odczytuję napięcie z ina219. Pętla wykonuje się prawidłowo wystawiłem sobie wartości Last i Now na port szeregowy i zobaczyłem jak wyglądają stany 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

1 godzinę temu, Belferek napisał:

Tak z ciekawości to gdzie dokonujesz tych odczytów bo na pewno nie w pętli do {} while?

Last = 0;

do{
busVoltage_V = ina219.getBusVoltage_V();

if(busVoltage_V< 10.00) now = 1;

if (last!= now) LCD.print(„działa”);

last =now;

LCD.print(now);

Lcd.print(last);

}while(1);

Tak to napisałem jeżeli dodam kolejnego IF z sprawdzeniem 11.00V to muszę wpisać 0.

na wyświetlaczu widzę jak zmieniają się wsrtości last i now

 

 

Link do komentarza
Share on other sites

Oczywiście, że odczyt napięcia w pętli to nic złego.

3 godziny temu, Gal_kris napisał:

pytanie czy można tak zrobić by zawsze po wykonaniu pętli wartości last i now miały 0

Te zmienne możesz (jeśli potrzebujesz) w ostatnich dwóch instrukcjach pętli wyzerować - to chyba najprostszy (logiczny) sposób.

do
{
 [ciach]
 last=0;
 now=0;
}while(1);

Piszesz "po wykonaniu pętli" - zauważ, że twoja pętla nigdy się nie kończy. Warunek końcowy pętli while(1) zawsze jest prawdziwy.

Zauważ też, że korzystasz z warunku if w "połowiczny" sposób. Pełna konstrukcja tego warunku to  if ... else ... Może warto z tego korzystać?

Link do komentarza
Share on other sites

5 godzin temu, Belferek napisał:

Oczywiście, że odczyt napięcia w pętli to nic złego.

Te zmienne możesz (jeśli potrzebujesz) w ostatnich dwóch instrukcjach pętli wyzerować - to chyba najprostszy (logiczny) sposób.

do
{
 [ciach]
 last=0;
 now=0;
}while(1);

Piszesz "po wykonaniu pętli" - zauważ, że twoja pętla nigdy się nie kończy. Warunek końcowy pętli while(1) zawsze jest prawdziwy.

Zauważ też, że korzystasz z warunku if w "połowiczny" sposób. Pełna konstrukcja tego warunku to  if ... else ... Może warto z tego korzystać?

Tak zauważyłem to i już przerobiłem, doczytałem gdzieś: pamiętaj, byś zawsze zadbał o to by pętla miała wyjście.

Link do komentarza
Share on other sites

Należy opisać co program ma robić i następnie wrzucać kod ( cały).  Uniknie się w ten sposób wielu niejasności.  Np. 

Potrzebuję zmierzyć napięcie na bateriach , zakres do 2 V. Używam arduino uno, programuję w  bascomie . Mam zmienne takie i oczekuję takiego rezultatu. Zamieszczam tutaj mój orogram oraz schemat ideowy. 

Mam pytanie dlaczego zmienna Czas1 nigdy się nie zmienia podczas gdy zmienna Wczas skacze losowo ?

😀

Czym więcej opiszesz tym więcej ludzie ci pomogą. 

Miłej zabawy !

 

Link do komentarza
Share on other sites

Dnia 25.11.2023 o 20:38, Santiago napisał:

Należy opisać co program ma robić i następnie wrzucać kod ( cały).  Uniknie się w ten sposób wielu niejasności.  Np. 

Potrzebuję zmierzyć napięcie na bateriach , zakres do 2 V. Używam arduino uno, programuję w  bascomie . Mam zmienne takie i oczekuję takiego rezultatu. Zamieszczam tutaj mój orogram oraz schemat ideowy. 

Mam pytanie dlaczego zmienna Czas1 nigdy się nie zmienia podczas gdy zmienna Wczas skacze losowo ?

😀

Czym więcej opiszesz tym więcej ludzie ci pomogą. 

Miłej zabawy !

 

Witaj, w sumie masz rację, mam sporą dysekcję i nie rozumiem warunków logicznych. Nikt mi raczej nie pomoże, będziecie się denerwować i ignorować to co wypisuję. Mam swoją metodę na zapamiętanie <- nie koniecznie zrozumienie jak to ma działać. Uczę się sam.

Od bardzo długiego czasu staram się zmusić esp32 do wysyłania maila o stanie napięcia na akumulatorze, chcę sobie polepszyć oryginalną konstrukcję ładowarki samochodowej. Sam kod wysyłki maila pobrałem z netu i jest on dla mnie zrozumiały, warunki IF też są bardzo zrozumiałe  ale pętle nie są tak dokładnie opisane jak tego wymagam by to zrozumieć. Stąd sporo moich testów i wstawiam w kod wiele testowego wysyłanie stanu na ekran LCD w ten sposób dowiaduję się gdzie utykam.

Nie zamierzam się poddać codziennie szukam rozwiązań.

Krystian

  • Lubię! 1
Link do komentarza
Share on other sites

#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
#define ETH_PHY_POWER 12
//#include <ESPAsyncWebServer.h>
#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <ESP_Mail_Client.h>
#include <WiFiUdp.h>
#include <LiquidCrystal_I2C.h>
#include <NTPClient.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
#include <INA219_WE.h>
#define I2C_ADDRESS 0x44
INA219_WE ina219 = INA219_WE(I2C_ADDRESS);
int lcdColumns = 16;
int lcdRows = 4;
LiquidCrystal_I2C lcd(0x3E, lcdColumns, lcdRows);
int last;
int now;
int no;
const int Analog_channel_pin= 39;
int ADC_VALUE = 0;
double voltage_value = 0;
float busVoltage_V = 0.0;
const int output32 = 32;
const int output33 = 33;
#define WIFI_SSID ""
#define WIFI_PASSWORD ""

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

/* The sign in credentials */
#define AUTHOR_EMAIL ""
#define AUTHOR_PASSWORD ""

/* Recipient's email*/
#define RECIPIENT_EMAIL ""

/* The SMTP Session object used for Email sending */
SMTPSession smtp;

//IPAddress ip(192, 168, 1, 98); // where xx is the desired IP Address
//IPAddress gateway(192, 168, 1, 1);

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);

void setup(){
  Serial.begin(115200);
   lcd.init();
   lcd.backlight();
   ina219.init();
   ina219.setADCMode(SAMPLE_MODE_128);
   busVoltage_V = ina219.getBusVoltage_V();
  Serial.println();
  Serial.print("Connecting to AP");
 //IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network
 // WiFi.config(ip, gateway, subnet); 
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
 /*
  Set the NTP config time
  For times east of the Prime Meridian use 0-12
  For times west of the Prime Meridian add 12 to the offset.
  Ex. American/Denver GMT would be -6. 6 + 12 = 18
  See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
  */
  timeClient.begin();
 // config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
 // config.time.gmt_offset = 3;
//  config.time.day_light_offset = 0;
  
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    lcd.setCursor(0,0);
    lcd.print("Brak WIFI");
    delay(200);
    lcd.clear();
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  lcd.setCursor(0,3);
  lcd.print(WiFi.localIP());
  busVoltage_V = ina219.getBusVoltage_V();
  //Serial.print(busVoltage_V);
  //Serial.println();
}

void loop(){

timeClient.update(); 
Serial.println(timeClient.getFormattedTime());
Serial.println(timeClient.getDay());
lcd.setCursor(0,1);
lcd.print(busVoltage_V);
lcd.setCursor(0,0);
lcd.print("                    ");
{


//------------------------------------------------------ wysyłka maila
last = -1; //ustawiam last na różne od 0
no = 0; // ustawiam while na 0
do{
busVoltage_V = ina219.getBusVoltage_V();// wymagane do odczytu napięcia w pętli
if (busVoltage_V <10.00) {// ustawia warunek jeśli spadnie poniżej 10V

now = busVoltage_V <10.00;// ustawiam napięcia na wartość now
no = 1;// ustawiam while na 1

}else{

no = 0;// jeśli warunek nie spełniony wartość while na 0
lcd.setCursor(0,0);
lcd.print("10");
delay(200);
//break;
}
if (busVoltage_V >11.00){

now = busVoltage_V >11.00;
no = 1;
}else{
 no = 0;
lcd.setCursor(5,0);
lcd.print("11");
delay(200);
//break;
}
if (busVoltage_V >13.70){ 

now = busVoltage_V >13.70;
no = 1;
}else{
no = 0;
lcd.setCursor(9,0);
lcd.print("13");
delay(200);
//break;
}
if(last!= now) email();// jeśli różnica last = now wyslij maila
lcd.setCursor(10,1);
lcd.print(now);

last = now; // wyrównuję wartości
lcd.setCursor(11,1);
lcd.print(last);
no = 0;// tu mam problem ponieważ jeśli watość while jest 1 pętla działa prawidłowo wysyła jesnego maila i czeka, jeśli jest 0 nadal wysyła maile jeden za drugim
} while(no);
lcd.setCursor(14,0);
lcd.print("ok");// jestem za pętlą
delay(200);

//------------------------------------------------------/koniec wysyłki maila
}

}

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status){
  /* Print the current status */
  Serial.println(status.info());

  /* Print the sending result */
  if (status.success()){
 
    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());
    Serial.println("----------------\n");
    struct tm dt;

    for (size_t i = 0; i < smtp.sendingResult.size(); i++){
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);
      time_t ts = (time_t)result.timestamp;
      localtime_r(&ts, &dt);

      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject);
    }
    Serial.println("----------------\n");
  }
}
void email ()
{
 /** Enable the debug via Serial port
   * none debug or 0
   * basic debug or 1
  */
  smtp.debug(1);

  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

  /* Declare the session config data */
  ESP_Mail_Session session;

  /* Set the session config */
  session.server.host_name = SMTP_HOST;
  session.server.port = SMTP_PORT;
  session.login.email = AUTHOR_EMAIL;
  session.login.password = AUTHOR_PASSWORD;
  session.login.user_domain = "";

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = "ESP";
  message.sender.email = AUTHOR_EMAIL;
  message.subject = "ESP Zarządzanie ładowaniem akumulatorów";
  message.addRecipient("Wartość zasialnia", RECIPIENT_EMAIL);

  /*Send HTML message*/
 
  String (busVoltage_V)+ String ("V  ")+ String ("Ładowanie");
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

  if (!smtp.connect(&session))
    return;

  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message))
   Serial.println("Error sending Email, " + smtp.errorReason());
   lcd.setCursor(0,0);
lcd.print("Send email");
delay(1000);
lcd.setCursor(0,0);
lcd.print("               ");
//lcd.setCursor(0,1);
//lcd.print(busVoltage_V);
}
void email1 ()
{
 /** Enable the debug via Serial port
   * none debug or 0
   * basic debug or 1
  */
  smtp.debug(1);

  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

  /* Declare the session config data */
  ESP_Mail_Session session;

  /* Set the session config */
  session.server.host_name = SMTP_HOST;
  session.server.port = SMTP_PORT;
  session.login.email = AUTHOR_EMAIL;
  session.login.password = AUTHOR_PASSWORD;
  session.login.user_domain = "";

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = "ESP";
  message.sender.email = AUTHOR_EMAIL;
  message.subject = "ESP Zarządzanie ładowaniem akumulatorów";
  message.addRecipient("Wartość zasialnia", RECIPIENT_EMAIL);

  /*Send HTML message*/
  //String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</h1><p>- Sent from ESP board</p></div>";
  String textMsg = "Ładuje, jest już "   +
  String (busVoltage_V)+ String ("V  ")+ String ("Naładowane");
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

  if (!smtp.connect(&session))
    return;

  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message))
   Serial.println("Error sending Email, " + smtp.errorReason());
}

Forumowicze oto cały kod nad którym siedzę wstawiłem komentarze  w void loop z moich testów wynika że nie mogę ingerować w działanie pętli do while aż tak mocno jak chciałem bo inaczej pętla nie działa prawidłowo.

Zobaczcie czy moje przemyślenia mają rację bytu.

założenie jest takie;

włączam układ do zasilania na aku jest prawidłowe napięcie układ wysyła mi maila o stanie akumulatora

jeśli napięcie spadnie poniżej 10v włączam ładowanie i informuję mailem o tym fakcie

później mogę informować o postępach ładowania ale raczej przedział 11v zrobiłem po to bym wiedział że akumulator jednak się ładuje i też wysyłam maila

ostatecznie gdy osiągnie 13,8 kończę ładowanie i wysyłam maila.

Tak wiem skąd będę wiedział że jest ładowanie skoro jak wejdzie napięcie ładowania to stale będę miał ponad 13V, to  na razie nie istotne bawię się i uczę 

Krystian

  • Lubię! 1
Link do komentarza
Share on other sites

40 minut temu, Gal_kris napisał:
no = 0;// tu mam problem ponieważ jeśli watość while jest 1 pętla działa prawidłowo wysyła jesnego maila i czeka, jeśli jest 0 nadal wysyła maile jeden za drugim
} while(no);

Ta pętla nigdy się nie kończy (nie da się z niej wyjść) bo no = 0

Link do komentarza
Share on other sites

(edytowany)
Dnia 27.11.2023 o 11:16, Belferek napisał:

Ta pętla nigdy się nie kończy (nie da się z niej wyjść) bo no = 0

To dlaczego z moich testów wychodzi zupełnie co innego, gdy jest 0 pętla while nie istnieje zobacz w kodzie dostaję na wyświetlacz info ok, za to gdy jest 1 pętla blokuje mi całe loop wyświetlacz milczy nie odświeża a przy 0 przelatuje dalej o co biega ?

Edytowano przez Gal_kris
błąd
Link do komentarza
Share on other sites

2 godziny temu, Gal_kris napisał:

To dlaczego z moich testów wychodzi zupełnie co innego

Cudów nie ma, procesory raczej się nie mylą, a odpowiedź na Twoje pytanie jest jedna = źle testujesz.

Zauważ, że pętla do {} while() zawsze wykona się przynajmniej raz pod warunkiem, że program do niej "dojdzie".

Dnia 27.11.2023 o 10:34, Gal_kris napisał:
/------------------------------------------------------ wysyłka maila
last = -1; //ustawiam last na różne od 0
no = 0; // ustawiam while na 0
do{

Dlaczego niby ta pętla do{ ma się nie wykonać jeśli program dojdzie do no = 0; ? Swoją drogą czy ogarniasz w swoim kodzie te nawiasy klamrowe?

Powiedz mi jakie jest przeznaczenie tego nawiasu?

Dnia 27.11.2023 o 10:34, Gal_kris napisał:
lcd.print("                    ");
{

Znajdziesz go zaraz na początku loop(). Ja nie mam pojęcia, a Ty? Stosuj wcięcia (tabulator), a program będzie bardziej czytelny. Możesz także wyświetlać numery wierszy wtedy mówiąc o programie będzie można się do tych numerów odnosić.

 

Edytowano przez Belferek
Link do komentarza
Share on other sites

Dziękuję że mi pomagacie, wszystkim bardzo dziękuję.

 

co do tego pustego nawiasu kasuję w ten sposób daną linię na wyświetlaczu bowiem ten sterownik (biblioteka) jest nie zgodny z esp32 nie znalazłem innego.

natomiast dlaczego przed pętlą ustawiam ten parametr no=0  ponieważ powoduje on że Procek nie reaguje na pętlę i program dochodzi do IF odczyt no=1 wtedy zostaje uwięziony w pętli a przynajmniej tak wychodzi z moich testów.

widzę jednak żeby pętla po spełnieniu warunku IF odczyt wysłała maila i na tym zakończyła wysyłkę nie mogę ingerować w parametr no= tam musi być 1.

tak jak już pisałem pętla gdy ma tę jedynkę blokuje cały void loop i nie mogę wtedy obserwować zmieniającego się napięcia na wyświetlaczu. Zasugerowałeś mi wcięcia i porządek zaraz to poprawię i zobaczę czy to pomoże

Krystian

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.