Cyclic restart and hang

Post here first, or if you can't find a relevant section!
Post Reply
forfrends
Posts: 14
Joined: Mon Jan 20, 2020 10:49 am

Cyclic restart and hang

Post by forfrends »

Hello.
Sorry for my english. I use a translator.
I am using STM32F103C8T6 (Blue Pill).
I faced an incomprehensible situation. I want to make a device for testing Li-ion batteries. Here is a link to the device diagram: https://easyeda.com/igor.silenock/li-ion-batterycharger
Here is a sketch:

Code: Select all

#include <OneWire.h>
#include <DallasTemperature.h>
#include <RTClock.h>

#define BTN     PB0
#define Buzzer  PB12
#define FAN     PC13
#define ONE_WIRE_BUS    PB6

RTClock rt (RTCSEL_LSE); // initialise
uint32 tt; 

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress sensor1 = {0x28, 0xFF, 0x23, 0x29, 0x21, 0x17, 0x4, 0xC1};
DeviceAddress sensor2 = {0x28, 0xFF, 0x7E, 0x0, 0x21, 0x17, 0x4, 0x5B};
DeviceAddress sensor3 = {0x28, 0xFF, 0x4A, 0x7, 0x21, 0x17, 0x4, 0x46};
DeviceAddress sensor4 = {0x28, 0xFF, 0x64, 0x2B, 0x21, 0x17, 0x4, 0x7E};
DeviceAddress sensor5 = {0x28, 0xFF, 0x78, 0x4, 0x21, 0x17, 0x4, 0xC9};

#define MaxTemp 60.0

byte Update = false;
char Buffer1[] = "Hello String";
char Buffer2[] = "Hello String";
//          Battery:     |#1   |#2   |#3   |#4
byte PinBattVoltage[] = {PA0,  PA2,  PA4,  PA6};   // Analog Input. Battery Voltage
byte PinLoadVoltage[] = {PA1,  PA3,  PA5,  PA7};   // Analog Input. Load Voltage
byte LoadON[]         = {PA15, PB1,  PB10, PB11};  // Digital Output. Load on: HIGH
byte ChargingON[]     = {PB9,  PB5,  PA12, PB15};  // Digital Output. Charging On: HIGH
byte ChargingRED[]    = {PB8,  PB4,  PA11, PB14};  // Digital Input. Charging. HIGH - disable; LOW - ensble
byte ChargingBLUE[]   = {PB7,  PB3,  PA8,  PB13};  // Digital Input. Charging Ended. HIGH - disable; LOW - ensble

float Res_Value[] = {10.0, 10.1, 9.85, 9.9};     // Resistor Value in Ohm


byte BatNum = 0;
byte Mode[] = {0, 0, 0, 0};
float BattVoltage[] = {0.0, 0.0, 0.0, 0.0};
float LoadVoltage[] = {0.0, 0.0, 0.0, 0.0};   // Voltage at lower end of the Resistor 
float ValueCorrect[] = {0.0, -0.0022, -0.0026, -0.0022};     // Resistor Value in Ohm

float BatCapacity[] = {0.0, 0.0, 0.0, 0.0};   // Capacity in mAh
float Current[] = {0.0, 0.0, 0.0, 0.0};    // Current in Amp
float mA=0;             // Current in mA
#define Bat_Low 3.0 // Discharge Cut Off Voltage

byte CountS[] = {0, 0, 0, 0};   //  seconds
byte CountM[] = {0, 0, 0, 0};   //  Minutes
byte CountH[] = {0, 0, 0, 0};   //  hours

byte Sound[] = {0, 0, 0, 0};
byte SoundCount = 0;
#define SoundCountMax 10

byte FanOn[] = {0, 0, 0, 0};

byte TestCount[] = {0, 0, 0, 0};

//int Button(0,    2048, 2730, 3079)
int ButtonL[] = {0, 1600, 2400, 2930};
int ButtonH[] = {1000, 2300, 2910, 3300};

//byte Vmesure = false;
byte EnableButton[] = {0, 0, 0, 0};

#define r1 9990.0
#define r2 17940.0

#define DC 1800
int DelayCount[] = {DC, DC, DC, DC};

void SecondsInterrupt()       // This function is called in the attachSecondsInterrpt
{
    Update = true;
}

//volatile uint32_t *px = (volatile uint32_t*)0x40005C40; // отключение пинов PA11 и PA12 от подключения к USB и использования в своих целях

void setup() 
{
    //*px = 0x2;                          // отключение пинов PA11 и PA12 от подключения к USB и использования в своих целях
    Serial.end();
    
    for(BatNum = 0; BatNum<4; BatNum++){
        pinMode(PinBattVoltage[BatNum], INPUT_ANALOG);
        pinMode(PinLoadVoltage[BatNum], INPUT_ANALOG);
        pinMode(LoadON[BatNum], OUTPUT);
        digitalWrite(LoadON[BatNum], LOW);
        pinMode(ChargingON[BatNum], OUTPUT);
        digitalWrite(ChargingON[BatNum], LOW);
        pinMode(ChargingRED[BatNum], INPUT);
        pinMode(ChargingBLUE[BatNum], INPUT);
    }
    
    pinMode(BTN, INPUT_ANALOG);
    pinMode(Buzzer, OUTPUT);
    pinMode(FAN, OUTPUT);
    digitalWrite(Buzzer, LOW);
    digitalWrite(FAN, LOW);
    
    Serial1.begin(9600);
    rt.attachSecondsInterrupt(SecondsInterrupt);// Call SecondsInterrupt

    sensors.begin();
    sensors.setResolution(sensor1, 9);
    sensors.setResolution(sensor2, 9);
    sensors.setResolution(sensor3, 9);
    sensors.setResolution(sensor4, 9);
    sensors.setResolution(sensor5, 9);
    Serial1.print("page 3");
    EndCommand();
}

void loop() 
{
    if (Update){                // если разрешено обновление дисплея
        Update = false;
        Serial1.println("1");
        sensors.requestTemperatures(); // Send the command to get temperatures

        if (sensors.getTempC(sensor2) > MaxTemp || sensors.getTempC(sensor3) > MaxTemp || sensors.getTempC(sensor4) > MaxTemp || sensors.getTempC(sensor5) > MaxTemp){
            Mode[0] = 8;
            Mode[1] = 8;
            Mode[2] = 8;
            Mode[3] = 8;
            FanOn[0] = 1;
            Serial1.print("page 2");
            EndCommand();
            beep();
        }else if (sensors.getTempC(sensor1) > MaxTemp){
            Mode[0] = 9;
            Mode[1] = 9;
            Mode[2] = 9;
            Mode[3] = 9;
            FanOn[0] = 1;
            Serial1.print("page 1");
            EndCommand();
            beep();
        }
        Serial1.println("2");
        V_meter();
        
        for(BatNum = 0; BatNum<4; BatNum++){

            if (BattVoltage[BatNum] < 2.0){
                Mode[BatNum] = 0;
            }

            if (EnableButton[BatNum] > 0){
                EnableButton[BatNum]--;
            }else{
                buttonRead(BatNum);
            }
            
            switch (Mode[BatNum]) {
                case 0:         // Нет аккумулятора, ожидание установки аккумулятора
                    {//Вывод на дисплей картинки отключенного аккумулятора
                    DisplayNoBattery(BatNum);
                    
                    digitalWrite(LoadON[BatNum], LOW);
                    digitalWrite(ChargingON[BatNum], LOW);
                    CountS[BatNum] = 0; // обнуление переменных времени
                    CountM[BatNum] = 0;
                    CountH[BatNum] = 0;
                    BatCapacity[BatNum] = 0.0;  // обнуление переменной емкости
                    Sound[BatNum] = 0;
                    FanOn[BatNum] = 0;
                    TestCount[BatNum] = 0;
                    DelayCount[BatNum] = DC;
                    Current[BatNum] = 0.0;
                    
                    if (BattVoltage[BatNum] > 2.0){
                        Mode[BatNum] = 1;
                        DisplayBattery(BatNum);
                    }
                    }
                    break;
        
                case 1:         // Аккумулятор обнаружен. Ожидание старта программы
                    {//Вывод на дисплей:
                    //  картинки аккумулятора
                    //  напряжение на аккумуляторе
                    //  ожидание старта (нажатия кнопки)
                    DisplayBattery(BatNum);
                    }
                    break;

                case 2:         // Заряд аккумулятора
                    {//Вывод на дисплей:
                    //  картинки заряжающегося аккумулятора
                    //  напряжение на аккумуляторе
                    //включение заряда
                    //проверка состояния зарядного устройства - ожидание окончания заряда
                    //обнуление переменной таймера
                    //время

                    digitalWrite(ChargingON[BatNum], HIGH);
                    digitalWrite(LoadON[BatNum], LOW);
                
                    CountTime(BatNum);
                    DelayCount[BatNum] = DC;
                    DisplayBatteryCharging(BatNum);
                    
                    if (digitalRead(ChargingRED[BatNum]) == HIGH){
                        if (digitalRead(ChargingBLUE[BatNum]) == LOW){
                            TestCount[BatNum]++;
                            if(TestCount[BatNum] > 5){
                                Mode[BatNum] = 3;
                                TestCount[BatNum] = 0;
                                DisplayBatteryPause(BatNum);
                            }
                        }else{
                            TestCount[BatNum] = 0;
                        }
                    }else{
                        TestCount[BatNum] = 0;
                    }

                    }
                    break;
                
                case 3:         // Пауза перед тестом для прекращения химических процессов
                    {//Вывод на дисплей:
                    //  картинки аккумулятора
                    //  напряжение на аккумуляторе
                    //  обратный отсчет таймера
                    //время
                    CountTime(BatNum);
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], LOW);

                    if (DelayCount[BatNum] > 0){
                        DelayCount[BatNum]--;
                        DisplayBatteryPause(BatNum);
                    }else{
                        Mode[BatNum] = 4;
                        DelayCount[BatNum] = DC;
                        DisplayBatteryTest(BatNum);
                    }
                    
                    }
                    break;
                
                case 4:         // Тест/разряд аккумулятора
                    {//Вывод на дисплей:
                    //  картинки аккумулятора
                    //  напряжение на аккумуляторе
                    //  сила тока
                    //  емкость
                    //время
                    FanOn[BatNum] = 1;
                    CountTime(BatNum);
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], HIGH);
                    //                  3.58                0.013                   10                  0.3567
                    Current[BatNum] = (BattVoltage[BatNum] - LoadVoltage[BatNum]) / Res_Value[BatNum] * 1000.0;
                    BatCapacity[BatNum] = BatCapacity[BatNum] + (Current[BatNum] / 3600.0);                          // 1 Hour = 3600s
                    
                    DisplayBatteryTest(BatNum);
                    
                    if (BattVoltage[BatNum] < Bat_Low){
                        TestCount[BatNum]++;
                        if(TestCount[BatNum] > 5){
                            TestCount[BatNum] = 0;
                            Mode[BatNum] = 5;
                            DelayCount[BatNum] = DC;
                            digitalWrite(LoadON[BatNum], LOW);
                            digitalWrite(ChargingON[BatNum], LOW);
                            DisplayBatteryPause(BatNum);
                        }
                    }else{
                        TestCount[BatNum] = 0;
                    }
                    
                    }
                    break;

                case 5:         // Пауза для прекращения химических процессов
                    {//Вывод на дисплей:
                    //  картинки аккумулятора
                    //  напряжение на аккумуляторе
                    //  обратный отсчет таймера
                    //время
                    FanOn[BatNum] = 1;
                    CountTime(BatNum);
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], LOW);
                    if (DelayCount[BatNum] > 0){
                        DelayCount[BatNum]--;
                        DisplayBatteryPause(BatNum);
                    }else{
                        Mode[BatNum] = 6;
                        DelayCount[BatNum] = DC;
                        DisplayBatteryCharging(BatNum);
                    }
                    
                    }
                    break;
                
                case 6:         // Заряд аккумулятора
                    {//Вывод на дисплей:
                    //  картинки заряжающегося аккумулятора
                    //  напряжение на аккумуляторе
                    //включение заряда
                    //проверка состояния зарядного устройства - ожидание окончания заряда
                    //обнуление переменной таймера
                    //время
                    FanOn[BatNum] = 0;
                    digitalWrite(ChargingON[BatNum], HIGH);
                    digitalWrite(LoadON[BatNum], LOW);
                
                    CountTime(BatNum);
                    DelayCount[BatNum] = DC;

                    DisplayBatteryCharging(BatNum);
                    
                    if (digitalRead(ChargingRED[BatNum]) == HIGH){
                        if (digitalRead(ChargingBLUE[BatNum]) == LOW){
                            TestCount[BatNum]++;
                            if(TestCount[BatNum] > 5){
                                Mode[BatNum] = 7;
                                TestCount[BatNum] = 0;
                                DisplayBatteryTestEnd(BatNum);
                            }
                        }else{
                            TestCount[BatNum] = 0;
                        }
                    }else{
                        TestCount[BatNum] = 0;
                    }
                    
                    }
                    break;

                case 7:         // Конец программы.
                    //Вывод на дисплей:
                    //  картинки аккумулятора
                    //  напряжение на аккумуляторе
                    //  емкость
                    //время
                    // ожидание отключения аккумулятора
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], LOW);
                    Sound[BatNum] = 1;
                    DisplayBatteryTestEnd(BatNum);
                    break;

                case 8:         //ПЕРЕГРЕВ
                    //Вывод на дисплей:
                    //  картинки перегретого аккумулятора
                    
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], LOW);
                    beep();
                    FanOn[BatNum] = 1;
                    break;

                case 9:         //Внутренний ПЕРЕГРЕВ
                    //Вывод на дисплей:
                    //  картинки перегретого аккумулятора
                    
                    digitalWrite(ChargingON[BatNum], LOW);
                    digitalWrite(LoadON[BatNum], LOW);
                    beep();
                    FanOn[BatNum] = 1;
                    break;
            }
            //Serial1.println("");
        }
        //Vmesure = false;
        if(Sound[0] || Sound[1] || Sound[2] || Sound[3]){
            SoundCount++;
            if (SoundCount > SoundCountMax){
                beep();
                SoundCount = 0;
            }
        }
        if(FanOn[0] || FanOn[1] || FanOn[2] || FanOn[3]){
            digitalWrite(FAN, HIGH);
        }else{
            digitalWrite(FAN, LOW);
        }
    }
}

void EndCommand(){
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);
}

void DisplayNoBattery(int i){
    //t0.txt="NO"
    sprintf(Buffer1,"t%d.txt=\"NO\"", i * 4);
    Serial1.print(Buffer1);
    EndCommand();

    //t1.txt="Battery"
    sprintf(Buffer1,"t%d.txt=\"Battery\"", (i * 4) + 1);
    Serial1.print(Buffer1);
    EndCommand();

    //t2.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", (i * 4) + 2);
    Serial1.print(Buffer1);
    EndCommand();

    //t3.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", (i * 4) + 3);
    Serial1.print(Buffer1);
    EndCommand();

    //t16.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", i + 16);
    Serial1.print(Buffer1);
    EndCommand();

    //t20.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", i + 20);
    Serial1.print(Buffer1);
    EndCommand();

    //p1.pic=1
    sprintf(Buffer1,"p%d.pic=%d", i + 1, (i * 5) + 1);
    Serial1.print(Buffer1);
    EndCommand();
}

void DisplayBattery(int i){
    //t0.txt="Battery"
    sprintf(Buffer1,"t%d.txt=\"Battery\"", i * 4);
    Serial1.print(Buffer1);
    EndCommand();

    //t1.txt="inserted"
    sprintf(Buffer1,"t%d.txt=\"inserted\"", (i * 4) + 1);
    Serial1.print(Buffer1);
    EndCommand();

    //t2.txt="3.28 V"
    sprintf(Buffer1,"t%d.txt=\"", ((i * 4) + 2));
    Serial1.print(Buffer1);
    Serial1.print(BattVoltage[i]);
    Serial1.print(" V\"");
    EndCommand();

    //t3.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", (i * 4) + 3);
    Serial1.print(Buffer1);
    EndCommand();

    //t16.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", i + 16);
    Serial1.print(Buffer1);
    EndCommand();

    //t20.txt=" "
    sprintf(Buffer1,"t%d.txt=\" \"", i + 20);
    Serial1.print(Buffer1);
    EndCommand();

    //p1.pic=1
    sprintf(Buffer1,"p%d.pic=%d", i + 1, (i * 5) + 1);
    Serial1.print(Buffer1);
    EndCommand();
}

void DisplayBatteryCharging(int i){

    if (Mode[i] > 5 ){
        //t0.txt=""
        //Serial1.print("t");
        //Serial1.print(i * 4);
        //Serial1.print(".txt=");
        //Serial1.print("\"");
        sprintf(Buffer1,"t%d.txt=\"%d", i * 4);
        Serial1.print(Buffer1);
        Serial1.print(BatCapacity[BatNum]);
        Serial1.print("\"");
        EndCommand();
    
        //t1.txt=" "
        //Serial1.print("t");
        //Serial1.print((i * 4) + 1);
        //Serial1.print(".txt=");
        //Serial1.print("\"");
        //Serial1.print("mAh");
        //Serial1.print("\"");
        sprintf(Buffer1,"t%d.txt=\"mAh\"", (i * 4) + 1);
        Serial1.print(Buffer1);
        EndCommand();
    }else{
        //t0.txt=""
        sprintf(Buffer1,"t%d.txt=\" \"", i * 4);
        Serial1.print(Buffer1);
        EndCommand();
    
        //t1.txt=" "
        sprintf(Buffer1,"t%d.txt=\" \"", (i * 4) + 1);
        Serial1.print(Buffer1);
        EndCommand();
    }
    
    //t2.txt="3.28 V"
    Serial1.print("t");
    Serial1.print((i * 4) + 2);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BattVoltage[i]);
    Serial1.print(" V\"");
    EndCommand();

    //t3.txt=" "
    Serial1.print("t");
    Serial1.print((i * 4) + 3);
    Serial1.print(".txt=");
    Serial1.print("\"");
    sprintf(Buffer1,"%02d:%02d:%02d", CountH[i], CountM[i], CountS[i]);
    Serial1.print(Buffer1);
    Serial1.print("\"");
    EndCommand();

    //t16.txt=" "
    Serial1.print("t");
    Serial1.print(i + 16);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(" ");
    Serial1.print("\"");
    EndCommand();

    //t20.txt=" "
    Serial1.print("t");
    Serial1.print(i + 20);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("Charg.");
    Serial1.print("\"");
    EndCommand();

    //p1.pic=1
    Serial1.print("p");
    Serial1.print(i + 1);
    Serial1.print(".pic=");
    Serial1.print((i * 5) + 2);
    EndCommand();
}

void DisplayBatteryPause(int i){

    if (Mode[i] > 4){
        //t0.txt=" "
        Serial1.print("t");
        Serial1.print(i * 4);
        Serial1.print(".txt=");
        Serial1.print("\"");
        Serial1.print(BatCapacity[BatNum]);
        Serial1.print("\"");
        EndCommand();
    
        //t1.txt=" "
        Serial1.print("t");
        Serial1.print((i * 4) + 1);
        Serial1.print(".txt=");
        Serial1.print("\"");
        Serial1.print("mAh");
        Serial1.print("\"");
        EndCommand();
    }else{
        //t0.txt=" "
        Serial1.print("t");
        Serial1.print(i * 4);
        Serial1.print(".txt=");
        Serial1.print("\"");
        Serial1.print(" ");
        Serial1.print("\"");
        EndCommand();
    
        //t1.txt=" "
        Serial1.print("t");
        Serial1.print((i * 4) + 1);
        Serial1.print(".txt=");
        Serial1.print("\"");
        Serial1.print(" ");
        Serial1.print("\"");
        EndCommand();
    }
    
    //t2.txt="3.28 V"
    Serial1.print("t");
    Serial1.print((i * 4) + 2);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BattVoltage[i]);
    Serial1.print(" V\"");
    EndCommand();

    //t3.txt=" "
    Serial1.print("t");
    Serial1.print((i * 4) + 3);
    Serial1.print(".txt=");
    Serial1.print("\"");
    sprintf(Buffer1,"%02d:%02d:%02d", CountH[i], CountM[i], CountS[i]);
    Serial1.print(Buffer1);
    Serial1.print("\"");
    EndCommand();

    //t16.txt=" "
    Serial1.print("t");
    Serial1.print(i + 16);
    Serial1.print(".txt=");
    Serial1.print("\"");
    sprintf(Buffer1,"%02d:%02d", (DelayCount[i]/60), (DelayCount[i]%60));
    Serial1.print(Buffer1);
    Serial1.print("\"");
    EndCommand();

    //t20.txt="PAUSE"
    Serial1.print("t");
    Serial1.print(i + 20);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("PAUSE");
    Serial1.print("\"");
    EndCommand();

    //p1.pic=1
    Serial1.print("p");
    Serial1.print(i + 1);
    Serial1.print(".pic=");
    Serial1.print((i * 5) + 3);
    EndCommand();
}

void DisplayBatteryTest(int i){
    //t0.txt="236.54"
    Serial1.print("t");
    Serial1.print(i * 4);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BatCapacity[i]);
    Serial1.print("\"");
    EndCommand();
    
    //t1.txt="mAh"
    Serial1.print("t");
    Serial1.print((i * 4) + 1);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("mAh");
    Serial1.print("\"");
    EndCommand();

    //t2.txt="3.28 V"
    Serial1.print("t");
    Serial1.print((i * 4) + 2);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BattVoltage[i]);
    Serial1.print(" V\"");
    EndCommand();

    //t3.txt=" "
    Serial1.print("t");
    Serial1.print((i * 4) + 3);
    Serial1.print(".txt=");
    Serial1.print("\"");
    sprintf(Buffer1,"%02d:%02d:%02d", CountH[i], CountM[i], CountS[i]);
    Serial1.print(Buffer1);
    Serial1.print("\"");
    EndCommand();

    //t16.txt="mA"
    Serial1.print("t");
    Serial1.print(i + 16);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("mA");    //LoadVoltage[i]*1000);          //"mA");
    Serial1.print("\"");    
    EndCommand();

    //t20.txt="500.4"
    Serial1.print("t");
    Serial1.print(i + 20);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(Current[i]);
    Serial1.print("\"");
    EndCommand();

    //p1.pic=1
    Serial1.print("p");
    Serial1.print(i + 1);
    Serial1.print(".pic=");
    Serial1.print((i * 5) + 4);
    EndCommand();
}

void DisplayBatteryTestEnd(int i){
    //t0.txt="236.54"
    Serial1.print("t");
    Serial1.print(i * 4);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BatCapacity[i]);
    Serial1.print("\"");
    EndCommand();
    
    //t1.txt="mAh"
    Serial1.print("t");
    Serial1.print((i * 4) + 1);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("mAh");
    Serial1.print("\"");
    EndCommand();

    //t2.txt="3.28 V"
    Serial1.print("t");
    Serial1.print((i * 4) + 2);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(BattVoltage[i]);
    Serial1.print(" V\"");
    EndCommand();

    //t3.txt=" "
    Serial1.print("t");
    Serial1.print((i * 4) + 3);
    Serial1.print(".txt=");
    Serial1.print("\"");
    sprintf(Buffer1,"%02d:%02d:%02d", CountH[i], CountM[i], CountS[i]);
    Serial1.print(Buffer1);
    Serial1.print("\"");
    EndCommand();

    //t16.txt=" "
    Serial1.print("t");
    Serial1.print(i + 16);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print(" ");
    Serial1.print("\"");
    EndCommand();

    //t20.txt="END"
    Serial1.print("t");
    Serial1.print(i + 20);
    Serial1.print(".txt=");
    Serial1.print("\"");
    Serial1.print("END");
    Serial1.print("\"");
    EndCommand();

    //p1.pic=1
    Serial1.print("p");
    Serial1.print(i + 1);
    Serial1.print(".pic=");
    Serial1.print((i * 5) + 5);
    EndCommand();
}

void buttonRead(int BN){
    float sample = 0;
    
    for(int i=0; i<10; i++)
    {
        sample = sample + analogRead(BTN);   //read battery voltage
        delay(1);
    }
    sample = sample / 10;

    if(sample >= ButtonL[BN] && sample <= ButtonH[BN]){
        if(Mode[BN] > 1){
            Mode[BN] = 0;
            DisplayNoBattery(BN);
        }else{
            Mode[BN] = 2;
            DisplayBatteryCharging(BN);
        }
    }
    EnableButton[BN] = 1;
}

void beep()
{
    
    digitalWrite(Buzzer, HIGH);
    delay(200);
    digitalWrite(Buzzer, LOW);
    for(int i=0; i<4; i++)
    {
        Sound[i] = 0;
    }
}

void V_meter()
{
    //************ Measuring Battery and Resistor Voltage ***********    
    float sample[] = {0.0, 0.0, 0.0, 0.0};
    float sampleL[] = {0.0, 0.0, 0.0, 0.0};
    Serial1.println("11");
    for(int a=0; a<30; a++)
    {
        
        for(int b=0; b<4; b++)
        {
            Serial1.println(b);
            Serial1.println(sample[b]);
            Serial1.println(PinBattVoltage[b]);
            Serial1.println(PinLoadVoltage[b]);
            Serial1.println(analogRead(PinBattVoltage[b]));
            sample[b] = sample[b] + analogRead(PinBattVoltage[b]);   //read battery voltage
            sampleL[b] = sampleL[b] + analogRead(PinLoadVoltage[b]); // read Load voltage
        }
        delay(3);
    }
    Serial1.println("12");
    for(int ii=0; ii<4; ii++)
    {
        sample[ii] = sample[ii] / 30;
        sample[ii] = (sample[ii] * 3.3) / 4095.0;
        BattVoltage[ii] = sample[ii] / (r2 / (r1+r2));
        BattVoltage[ii] = BattVoltage[ii] - 0.01;       // корректировка показаний
        
        sampleL[ii] = sampleL[ii] / 30;
        sampleL[ii] = (sampleL[ii] * 3.3) / 4095.0;
        LoadVoltage[ii] = sampleL[ii] / (r2 / (r1+r2));
        LoadVoltage[ii] = LoadVoltage[ii] + ValueCorrect[ii]; //0.00245;       // корректировка показаний
    }
    Serial1.println("13");
}

void CountTime(int i)
{
    CountS[i]++;
    if (CountS[i] > 59){
        CountS[i] = 0;
        CountM[i]++;
        if (CountM[i] > 59){
            CountM[i] = 0;
            CountH[i]++;
        }
    }
}
The code is pretty big. I will try to briefly explain its essence. The device is designed for simultaneous testing of 4 batteries, so the variables are presented in the form of arrays, for more convenient rotation to the pins and variables.
The USBSeries is disabled because I use pins PA11 and PA12.
I do the data output by Serial1 (pins PA9, PA10) to the Nextion display.
I also use a clock chip connected to pins PC14 and PC15 for accurate synchronization. Once per second, an interrupt from the real-time clock is triggered, and permission to perform an action in the main program loop occurs:

Code: Select all

if (Update){...
Next, I check the temperature on the sensors DS18B20.

Code: Select all

if (sensors.getTempC(sensor2) > MaxTemp...
Next, the function of checking the voltage on the batteries (or their absence) is called:

Code: Select all

V_meter();
Variable BatNum is designed to switch between 4 batteries.

Code: Select all

for(BatNum = 0; BatNum<4; BatNum++){...
Depending on the operating mode, these or other functions are used:

Code: Select all

switch (Mode[BatNum]) {...
I will not explain each mode. Everything is well described in the code, but in Russian.
Yesterday, after the next firmware flashing to the controller, I found that pin RA15 does not work. I tried to write a simple sketch, blink, to control only RA15. But the pin still didn't work. I thought that I somehow ruined the pin of the microcontroller ... For the test, I installed another kernel to support STM32 and again flashed the blink program - and it worked!
So the problem was not in the microcontroller, but in the code, for some reason the kernel from stm32duino became buggy. Today I again started debugging the program. At some point, everything stopped working!
The program in the main loop is executed only 1 time. When re-entering "if (Update) {", the program reaches the call to the voltage measurement function "V_meter ();". Goes to this function. And the microcontroller completely freezes when receiving the value from the Analog input:

Code: Select all

sample[b] = sample[b] + analogRead(PinBattVoltage[b]);
At the same time, the RA13 LED flashes: https://youtu.be/eCc_lWA8J-E
I’ve been trying to get everything to work for several hours, but all to no avail!
Here is a link to the project that is created during the compilation of the sketch: https://drive.google.com/open?id=1EjgHH ... WpV_mjgQOO

I ask for your help in solving my problem, since I have reached a dead end ...
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: Cyclic restart and hang

Post by mrburnette »

Around line 24:

Code: Select all

bool volatile Update = false;
Post Reply

Return to “General discussion”