Выполнить некоторые команды только 1 раз.

pixel28
Offline
Зарегистрирован: 23.11.2015

Делаю тестер аккумуляторов.

Весь код выглядит вот так:

#include <LiquidCrystal.h>
 
int sensorPin = 0;    // к пину Analog IN 0
int sensor2Pin = 2;   // к пину Analog IN 2
int ledPin = 13;      // пин к затвору транзистора
 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // initialize the library with the numbers of the interface pins
 
int sensorValue = 0;  // variable to store the value coming from the sensor 
int sensor2Value = 0;  // variable to store the value coming from the sensor 
float LiMinThreshold = 2700; // Lithium Minimal Voltage for load removal
float LiMaxThreshold = 4200; // Lithium Max Voltage for load removal
float NmhMinThreshold = 950; // NMH Minimal Voltage for load removal
float NmhMaxThreshold = 1600; // NMH Max Voltage for load removal
float SelectedMinThreshold = 5000;
float current;
int i;
int BatVoltage = 5000;
int FetVoltage = 5000;
long TotalCurrent = 0;
boolean done = false;
unsigned long PrevMillis ;
unsigned long MillisPassed ;
 
void CL2(){
  lcd.setCursor(0, 1);// Second line first char
  lcd.print("                        ");
  lcd.setCursor(0, 1);// Second line first char
}  

void CL1(){
  lcd.setCursor(0, 0);// First line first char
  lcd.print("                        ");
  lcd.setCursor(0, 0);// First line first char
}
 
void setup() {
  pinMode(ledPin, OUTPUT);//activation led and enable for FET
  lcd.begin(16, 2);// set up the LCD's number of rows and columns: 
  
  lcd.print("     HELLO     ");  // Print a message to the LCD.
  
  lcd.setCursor(0, 1);// Second line first char
  lcd.print("Detecting Bat"); // print voltage value
  
  delay(2000);
   
  lcd.setCursor(0, 1);// Second line first char
  lcd.print("                        ");
  
  lcd.setCursor(0, 1);// Second line first char
  digitalWrite(ledPin, HIGH);   // set the LED on
  sensorValue = analogRead(sensorPin);   // read the value from the sensor:
  digitalWrite(ledPin, LOW);   // set the LED off
  // Detecting battery type
  BatVoltage = sensorValue*4.887;
  if (BatVoltage > 4500){
    lcd.print("Warning high-V! ");
    done = true;}
  else if (BatVoltage > LiMinThreshold){
    lcd.print("Type:Li-Ion Bat ");
    SelectedMinThreshold = LiMinThreshold;}
  else if (BatVoltage > NmhMinThreshold){
    lcd.print("Type:NiMH/Cd Bat ");
    SelectedMinThreshold = NmhMinThreshold;}
  else{
    lcd.print("Unknown Bat V < 1");
    done = true;}
  lcd.print("V=");
  lcd.print(sensorValue*4.887); // print voltage value
  delay(3000); 
  CL2();
  PrevMillis = millis();
}
 
void loop() {

      int time = millis() / 1000;
    
      if (BatVoltage > SelectedMinThreshold && !done) {
      digitalWrite(ledPin, HIGH);   // set the LED on
      sensorValue = analogRead(sensorPin);   // read the value from the sensor:
      sensor2Value = analogRead(sensor2Pin);   // read the value from the FET:
      FetVoltage = (sensor2Value*4.887);
      BatVoltage = (sensorValue*4.887);
      current = (BatVoltage/3.3);
      
      lcd.clear();
      
      lcd.setCursor(0, 0);// First line first char
      TotalCurrent=TotalCurrent+MillisPassed/1000*(BatVoltage-FetVoltage)/3.3/3.6;
      lcd.print("    I=");
      lcd.print(TotalCurrent/1000);     
      lcd.print("mAH");
      

      lcd.setCursor(0, 1);// Second line first char
      lcd.print("V=");
      lcd.print(BatVoltage/1000.0); // print voltage value
      lcd.print("V ");

      
      lcd.print("A=");
      lcd.print(current/1000);
      lcd.print("A"); 
      
      
      delay(1000); 
      MillisPassed = millis()- PrevMillis;
      PrevMillis = millis();
      
     
    }
    else
    {
      done=true;
      digitalWrite(ledPin, LOW);   // set the LED off - stop loading
      CL2();

       lcd.setCursor(4, 0);
        if (time / 60 / 60 < 10) {
          lcd.print ("0");                  //часы
      }
      lcd.print (time / 60 / 60);
      lcd.print (":");
        if (time / 60 % 60 < 10) {
          lcd.print ("0");                  //минуты
      }
      lcd.print ((time / 60) % 60);
      lcd.print (":");
        if (time%60<10) { lcd.print ("0"); }//секунды
          lcd.print (time%60);
          
      sensorValue = analogRead(sensorPin);   // read the value from the sensor:
      BatVoltage = (sensorValue*4.887);
      lcd.setCursor(0, 1);// Second line first char
      lcd.print("V=");
      lcd.print(BatVoltage/1000.0); // print voltage value
      lcd.print("V ");
      lcd.print("I=");
      lcd.print(TotalCurrent/1000);     
      lcd.print("mAH");

      delay(1000);
    }
}

Когда тест заканчивается, выполняется все, что под:

done = true;

С самого начала теста у меня идет отсчет времени и в конце должно отображаться время, затраченное на тест(грубо говоря на "void loop()").

Но у меня время тикает после теста тоже.

Нужно выполнить этот кусок кода только один раз. Вывод сделан так: 

lcd.setCursor(4, 0);
        if (time / 60 / 60 < 10) {
          lcd.print ("0");                  //часы
      }
      lcd.print (time / 60 / 60);
      lcd.print (":");
        if (time / 60 % 60 < 10) {
          lcd.print ("0");                  //минуты
      }
      lcd.print ((time / 60) % 60);
      lcd.print (":");
        if (time%60<10) { lcd.print ("0"); }//секунды
          lcd.print (time%60);

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

вначале сделай какую нибудь булевую переменную, приравняй к ложь, сделай вывод при условии что это переменная ложь. когда сделаешь вывод проровняй ее к тру и больше этот вывод проводиться не будет.

inspiritus
Offline
Зарегистрирован: 17.12.2012

После этого блока подожди до нажатия чего нибудь, потом перезапусти все сначала программным ресетом.

pixel28
Offline
Зарегистрирован: 23.11.2015

Я в ардуино совсем новичок. Пробовал много разных способов, в итоге у меня получилось!!. Не знаю правильно ли это, но зато работает))

 while(i < 1) 
    {
        i++;  
     lcd.setCursor(4, 0);
        if (time / 60 / 60 < 10) {
          lcd.print ("0");                  //часы
      }
      lcd.print (time / 60 / 60);
      lcd.print (":");
        if (time / 60 % 60 < 10) {
          lcd.print ("0");                  //минуты
      }
      lcd.print ((time / 60) % 60);
      lcd.print (":");
        if (time%60<10) { lcd.print ("0"); }//секунды
          lcd.print (time%60);
    }

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

ну можно и так а то про что я говорил в Вашем случае i должна быть булевой, то есть инициироваться она должна bool i=false;

в строке 1 пишем if(!i)//восклицательный знак перед переменной возвращает "инвертированное" ее значение, то есть в скобках у нас должно быть тру, так чтобы код в if фигурных скобках выполнялся,( тоже самое про while но это немного другое), а так как у нас i изначально равно false то !i=true. или можно было написать if(i==false). чем мне нравятся булевые переменные так это тем что не нужно под них писать равны они чему или нет, просто их указывать в скобках. if(i) или if(!i) или if(i&&y) или if(i&&!y)..

в строке 3 пишем i=true;

ПС если вы новичек то помогает обильные коментарии в скетче, берите готовые и читайте их, поймете как что делается...

MacSim
Offline
Зарегистрирован: 28.11.2012

Mr.Privet пишет:

ну можно и так а то про что я говорил в Вашем случае i должна быть булевой, то есть инициироваться она должна bool i=false;

булевая не булевая... лично мне на фелс и тру проверять не очень нравиться: в памяти мк ей отводиться байт, а используется только два значения... чуете к чему я? в переменную можно загнать не один флаг, а больше. каждый бит можно как флаг использовать. вместо 8 булевых, которые в памяти займут 8 байт - можно занять 1 байт. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Смотри.

void do_one_time(){
  static uint8_t one= 0;// это переменая которая разрешает выполнить 1 раз
  if (one ) return;
  one = 1;
  // здесь код который надо выполнить 1 раз
}
void setup() {


}

void loop() {
 do_one_time();// вызывается много но делает 1 раз

}

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

MacSim пишет:

булевая не булевая... лично мне на фелс и тру проверять не очень нравиться: в памяти мк ей отводиться байт, а используется только два значения... чуете к чему я? в переменную можно загнать не один флаг, а больше. каждый бит можно как флаг использовать. вместо 8 булевых, которые в памяти займут 8 байт - можно занять 1 байт. 


Ну да, только новичка это еще больше запутает, и большенство наших скетчиков в память не упираются. Хотя лучьше измальства учиться экономить