Skocz do zawartości

Logiczne 0 pętli do while


Pomocna odpowiedź

Napisano
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

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.

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 

tak w pętli czy to źle?

 

32 minuty temu, Belferek napisał:

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

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

 

 

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ć?

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.

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 !

 

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
#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
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

(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
(edytowany)
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

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

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...