Работа с памятью

MsFedkin
Offline
Зарегистрирован: 12.12.2017

 Всем привет, впервые пытаюсь работать с памятью. Получается относительно успешно.

 Имею следующий код(не весь): 

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();  
  }
}

В определенный момент плата зависает уверен что проблема в этой части кода.

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

На 146% прав.

b707
Offline
Зарегистрирован: 26.05.2017

MsFedkin пишет:

 В определенный момент плата зависает уверен что проблема в этой части кода.

может в этой, а может и в той. Ту мы не видели, может она хуже :)

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Еще один шпиён 008 )))

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

MsFedkin пишет:
уверен что проблема в этой части кода.
Ну, уверен, так уверен, а сюда-то зачем запостил?

MsFedkin
Offline
Зарегистрирован: 12.12.2017

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

b707
Offline
Зарегистрирован: 26.05.2017

MsFedkin пишет:

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

Уважаемый, не переживайте,  никого не интересуют ваши пропорции, можете их из кода выкинуть. Но код должен быть полный - то есть такой, который без изменений компилировался бы стандартным компилятором - и при этом демонстрировал ошибку.

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

Если не хотите показывать код - продолжать нет смысла.

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

MsFedkin пишет:
Всем привет, впервые пытаюсь работать с памятью. Получается относительно успешно.В определенный момент плата зависает уверен что проблема в этой части кода.

Утечка памяти. Очень хорошо вы с памятью работаете. Переходите на лодки. Открытие кингстонов очень хорошо учит плаванью в воде.

MsFedkin
Offline
Зарегистрирован: 12.12.2017

  Тогда ответе на такой вопрос почему условие

if(!count)
  {
   count = new uint64_t;
   *count = millis(); 
  }

 срабатывает только 1 раз.

А условие 

if(count){
        delete count;
}

 за 15 минут работы программы срабатывает 12к раз.

То есть память выделилась 1 раз а удаление ее происходит 12к раз. 

b707
Offline
Зарегистрирован: 26.05.2017

потому что очищение динамической переменной не приравнивает указатель нулю

что это за миллис такой у вас - 64 битный? Что за контроллер?

MsFedkin
Offline
Зарегистрирован: 12.12.2017

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);
  }

 

MsFedkin
Offline
Зарегистрирован: 12.12.2017

Arduino UNO R3

b707
Offline
Зарегистрирован: 26.05.2017

MsFedkin пишет:

Arduino UNO R3

 в Уно миллис имеет тип uint32_t

b707
Offline
Зарегистрирован: 26.05.2017

А можно узнать, в чем смысл этого "прыжка через голову" - выделения динамической переменной в прерывании? Чего вы хотите добиться-то? Почему не завести глобал вместо постоянных выделений и стираний жалких 8 байт?

Думаю, что это даже близко не работает так, как вы думали.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

А можно узнать, в чем смысл этого "прыжка через голову" ?

А эта оне образованность свою показать хочут! ;))))

 

b707
Offline
Зарегистрирован: 26.05.2017

насчет не_обнуления указателя при delete я там выше, похоже, фигню сморозил. Хотя проверять указатель таким образом на NULL не рекомендуется, в данном случае проблема в другом.

Все в прерывании сделано неверно