Работа с памятью
- Войдите на сайт для отправки комментариев
Ср, 09/10/2019 - 21:46
Всем привет, впервые пытаюсь работать с памятью. Получается относительно успешно.
Имею следующий код(не весь):
void loop {
if((!digitalRead(a)) && millis() - *count > 180000 && count){
... // какой-то код
}
if(moveDetectore.digitalRead(a)){
if(count)delete count;
... // какой-то код
}
}
// функция прерывание
void setOffTimer(void){
if(!count)
{
count = new uint64_t;
*count = millis();
}
else
{
*count = millis();
}
}
В определенный момент плата зависает уверен что проблема в этой части кода.
На 146% прав.
В определенный момент плата зависает уверен что проблема в этой части кода.
может в этой, а может и в той. Ту мы не видели, может она хуже :)
Еще один шпиён 008 )))
Там только решение пропорций,работа с аналоговым входам и выходами, короче вода всякая.
Там только решение пропорций,работа с аналоговым входам и выходами, короче вода всякая.
Уважаемый, не переживайте, никого не интересуют ваши пропорции, можете их из кода выкинуть. Но код должен быть полный - то есть такой, который без изменений компилировался бы стандартным компилятором - и при этом демонстрировал ошибку.
Важно видеть, как и когда вы описываете переменные, как выделяете и освобождаете память, да и многое другое. Вы - по определению - не можете знать, что является значимым для поиска ошибки в коде, а что нет, потому как если бы вы это знали - решили бы проблему сами.
Если не хотите показывать код - продолжать нет смысла.
Утечка памяти. Очень хорошо вы с памятью работаете. Переходите на лодки. Открытие кингстонов очень хорошо учит плаванью в воде.
Тогда ответе на такой вопрос почему условие
if(!count) { count = new uint64_t; *count = millis(); }срабатывает только 1 раз.
А условие
if(count){ delete count; }за 15 минут работы программы срабатывает 12к раз.
То есть память выделилась 1 раз а удаление ее происходит 12к раз.
потому что очищение динамической переменной не приравнивает указатель нулю
что это за миллис такой у вас - 64 битный? Что за контроллер?
1 часть кода основная программа:
#include "iopin_class.h" //подключение класса iopin_class // определение режима соединения и подключение библиотеки RemoteXY #define REMOTEXY_MODE__HARDSERIAL #define SDBG #include <RemoteXY.h> // настройки соединения #define REMOTEXY_SERIAL Serial #define REMOTEXY_SERIAL_SPEED 9600 // конфигурация интерфейса #pragma pack(push, 1) uint8_t RemoteXY_CONF[] = { 255,2,0,19,0,242,0,8,13,5, 4,128,6,23,49,6,1,2,26,129, 0,14,17,18,6,1,17,208,158,209, 129,208,178,208,181,209,137,208,181,208, 189,208,184,208,181,32,0,67,5,21, 37,20,5,1,2,26,6,2,0,14, 78,35,13,1,2,26,31,31,87,105, 114,101,108,101,115,115,0,65,117,116, 111,0,129,0,9,47,18,6,1,17, 208,160,208,181,208,182,208,184,208,188, 32,209,128,208,176,208,177,208,190,209, 130,209,139,32,0,66,129,9,22,45, 7,2,2,26,129,0,17,28,27,6, 1,17,208,151,208,189,208,176,209,135, 208,181,208,189,208,184,208,181,0,65, 4,16,62,9,9,1,65,4,41,62, 9,9,1,129,0,10,64,4,6,1, 17,65,0,129,0,32,64,6,6,1, 17,87,0,131,1,4,5,20,7,1, 2,31,80,97,103,101,49,0,131,0, 37,5,20,7,2,2,31,80,97,103, 101,50,0,129,0,24,14,14,6,2, 17,208,161,208,178,208,181,209,130,0, 67,5,20,34,23,5,2,2,26,6, 68,17,8,48,51,33,2,25,2 }; // структура определяет все переменные вашего интерфейса управления struct { // input variable int8_t slider; // =0..100 положение слайдера uint8_t Mode_switch; // =1 если переключатель включен и =0 если отключен // output variable char pwm_str[6]; // =строка UTF8 оканчивающаяся нулем char lightStr[8]; // =строка UTF8 оканчивающаяся нулем float onlineGraph_1; int8_t levelLight; // =0..100 положение уровня uint8_t flagAuto; // =0..255 яркость красного цвета индикатора uint8_t flagWireless; // =0..255 яркость красного цвета индикатора // other variable uint8_t connect_flag; // =1 if wire connected, else =0 } RemoteXY; #pragma pack(pop) //*** инициализация портов #define PIR_ISR 0 // номер прерывания 2 пин контроллера #define AIN A0 // аналоговый вход #define PWM_OUT 5 // ШИМ выход #define PIR 2 // ик детектор outPin led(PWM_OUT); // создание объекта светодиодов inPin luxmeter(AIN); inPin moveDetectore(PIR); volatile uint8_t lightSwitch; uint64_t* count; uint8_t pwm_val; // значени ШИМ сигнала #ifdef SDBG int i; int ii; int iii; int iiii; #endif void setOffTimer(void); //*** константы #define SLIDER_TO_PWM 2.55 void setup() { #ifdef SDBG Serial.begin(9600); #endif RemoteXY_Init (); // Инициализация Bluetooth attachInterrupt(PIR_ISR,setOffTimer,FALLING); pinMode(13,OUTPUT); } void loop() { #ifdef SDBG Serial.print(i); Serial.print("\t"); Serial.print(ii); Serial.print("\t"); Serial.print(iii); Serial.print("\t"); Serial.println(iiii); #endif RemoteXY_Handler (); if(RemoteXY.Mode_switch){ // если =1 то дистанционный pwm_val = (RemoteXY.slider * SLIDER_TO_PWM); // пропорция для перевода значения слайдера в значение ШИМ RemoteXY.flagAuto = 0; // индиктаор местного управления 0 RemoteXY.flagWireless = 255; // индикатор дистанционного 1 } else { pwm_val = (luxmeter.analogRead()*(-0.249 ) + 0xFF) * lightSwitch; // пропорция для перевода значения потенциометра в значение ШИМ RemoteXY.flagWireless = 0; // индикатор дистанционного 0 RemoteXY.flagAuto = 255; // индиктаор местного управления 1 if((!moveDetectore.digitalRead()) && (millis() - *count > 30000) ){ lightSwitch = 0x00; #ifdef SDBG i++; #endif } if(moveDetectore.digitalRead()){ if(count){ delete count; #ifdef SDBG ii++; #endif } lightSwitch = 0x01; } } led.analogWrite(pwm_val);// выдача ШИМ сигнала на порт itoa(pwm_val,RemoteXY.pwm_str,10);// преобразование int в строку itoa(1234,RemoteXY.lightStr,10); RemoteXY.onlineGraph_1 = (luxmeter.analogRead() + 0.5); RemoteXY.levelLight = (luxmeter.analogRead()/10.24); } void setOffTimer(void){ if(!count) { count = new uint64_t; *count = millis(); #ifdef SDBG iii++; #endif } else { *count = millis(); } #ifdef SDBG iiii++; #endif }2 часть
#include "Arduino.h" #include "iopin_class.h" //****** outPin outPin :: outPin(uint8_t _oPin): oPin(_oPin) { pinMode(oPin,OUTPUT); outputVal = NULL; } void outPin :: digitalWrite (uint8_t _outputVal) { outputVal = new uint8_t; *outputVal = _outputVal; :: digitalWrite(oPin,*outputVal); delete outputVal; } void outPin :: analogWrite (uint8_t _outputVal) { outputVal = new uint8_t; *outputVal = _outputVal; :: analogWrite(oPin,*outputVal); delete outputVal; } void outPin :: fakeWrite(uint8_t _outputVal) { outputVal = new uint8_t; *outputVal = _outputVal; *outputVal = (*outputVal * 1000)/255; :: digitalWrite(oPin, HIGH); delayMicroseconds(*outputVal); :: digitalWrite(oPin, LOW); delayMicroseconds(1000 - *outputVal); } void outPin :: blink () { this -> digitalWrite(!::digitalRead(oPin)); } //****** inPin inPin :: inPin(){} inPin :: inPin(uint8_t _iPin):iPin(_iPin) { pinMode(iPin,INPUT); } uint16_t inPin :: analogRead() { return :: analogRead(iPin); } bool inPin :: digitalRead () { return :: digitalRead(iPin); }Arduino UNO R3
Arduino UNO R3
в Уно миллис имеет тип uint32_t
А можно узнать, в чем смысл этого "прыжка через голову" - выделения динамической переменной в прерывании? Чего вы хотите добиться-то? Почему не завести глобал вместо постоянных выделений и стираний жалких 8 байт?
Думаю, что это даже близко не работает так, как вы думали.
А можно узнать, в чем смысл этого "прыжка через голову" ?
А эта оне образованность свою показать хочут! ;))))
насчет не_обнуления указателя при delete я там выше, похоже, фигню сморозил. Хотя проверять указатель таким образом на NULL не рекомендуется, в данном случае проблема в другом.
Все в прерывании сделано неверно