Оперативка

vlad072
Offline
Зарегистрирован: 01.08.2017

Собственно вопрос по "практической" опасной близости кучи к стеку, где критическая граница? Понятно, что компилятор будет предупреждать заранее, ещё за долго об этой опасности. Может кто сталкивался на практике с глюками по теме?

Скетч использует 16776 байт (54%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 1541 байт (75%) динамической памяти, оставляя 507 байт для локальных переменных. Максимум: 2048 байт.
Недостаточно памяти, программа может работать нестабильно.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Граница в сферическом скетче?

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

vlad072, вам что поговорить не о чем?

vlad072
Offline
Зарегистрирован: 01.08.2017

Да, вопрос задал сумбурно.. Правильней так: от чего в AVR в основном зависит размер стека, и в каких пределах он обычно разрастается на практике?

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

vlad072 пишет:

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

И не подумает. Вот даже в мыслях у него не будет.

b707
Онлайн
Зарегистрирован: 26.05.2017

vlad072 пишет:

Да, вопрос задал сумбурно.. Правильней так: от чего в AVR в основном зависит размер стека, и в каких пределах он обычно разрастается на практике?

Он не "разрастается". Он занимает ровно столько места, сколько требуют ваши временные и локальные переменные.

И еще отвечу не на ваш вопрос - однако по делу :)

Вот у вас кода всего 16К - а оперативки занято уже 1500 байт - и ЭТО НЕНОРМАЛЬНО. Ищите, куда вы дели такую прорву RAM.

Не обижайтесь, но скорее всего - вы банально не умеете писать эффективный код и не владеете приемами экономии памяти. Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ну так ты не берешь в ращёт, наерна, такие прожорливые биб-ки, как SD, OLED и т.д. мало ли что память жрать умеет как не в себя...

b707
Онлайн
Зарегистрирован: 26.05.2017

DetSimen пишет:

ну так ты не берешь в ращёт, наерна, такие прожорливые биб-ки, как SD, OLED и т.д. мало ли что память жрать умеет как не в себя...

беру. Использование библиотеки ОЛЕД с буфером в 1К - это тоже признак неумения экономить память :)

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

b707 пишет:

Не обижайтесь, но скорее всего - вы банально не умеете писать эффективный код и не владеете приемами экономии памяти. Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт

и как после этого дальше жить )))

vlad072
Offline
Зарегистрирован: 01.08.2017

b707 пишет:

Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт

Много строковых переменных для работы с модемом и iot. Из библиотек использую только SoftwareSerial и 1wire.

так хотелось бы узнать, что больше всего использует стек? Переменные функций в нём размещаются? И главный вопрос, стоит ли вообще париться при 25% свободной оперативки или это излишняя осторожность компилятора?

vlad072
Offline
Зарегистрирован: 01.08.2017

ua6em пишет:

и как после этого дальше жить )))

Конструктив так и прёт, трололо

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

vlad072 пишет:

так хотелось бы узнать, что больше всего использует стек? Переменные функций в нём размещаются? И главный вопрос, стоит ли вообще париться при 25% свободной оперативки или это излишняя осторожность компилятора?

Да, кто ж Вас знает, что там за скетч у Вас и что (а, главное, как) он использует?

Ну, попробуйте запустить с постоянным мониторингом памяти, увидите как оно меняется в процессе работы.

Вот в этой теме показано как следить за памятью в процессе выполнения программы.

b707
Онлайн
Зарегистрирован: 26.05.2017

vlad072 пишет:

Много строковых переменных для работы с модемом и iot.

ну вот именно это я и предполагал - не умеете работать с памятью. Строки во флеш класть не пробовали?

Цитата:
так хотелось бы узнать, что больше всего использует стек? Переменные функций в нём размещаются? И главный вопрос, стоит ли вообще париться при 25% свободной оперативки или это излишняя осторожность компилятора?

Повторяю, вы не о том думаете. Судя по многим признакам. память у вас кончилась потому. что код кривой. Так что правильный вопрос от вас должен звучать так: "Как мне уменьшить расход памяти в программе?" - а не "Где граница стека?" - на этот вопрос точно вам никто не ответит.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

у стека нет границы, у него есть только верхушка.  А она постоянна плавает. 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

у стека нет границы, у него есть только верхушка.  А она постоянна плавает. 

а 0x0000 ? надеюсь здесь он тоже вниз растёт?

vlad072
Offline
Зарегистрирован: 01.08.2017

b707 пишет:

Строки во флеш класть не пробовали?

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

#include <SoftwareSerial.h>
#include <OneWire.h>
#include <CyberLib.h>
#include "consts.h"
#include "classes.h"

SoftwareSerial gsm(SIM800RX_PIN, SIM800TX_PIN);
OneWire ds(ONEWIRE_PIN);
Input  lock(LOCK_PIN), door(DOOR_PIN), hood(HOOD_PIN), fuelpump(FUELPUMP_PIN);
Output siren(SIREN_PIN), flash(FLASH_PIN), dvr(DVR_PIN), led(LED_PIN);
InOut  ign(IGN_SUPPLY_PIN, IGN_PIN), starter(STARTER_SUPPLY_PIN, STARTER_PIN);

char     at[ 128 ] = "";
uint32_t tpingresp = 0;
uint32_t t30sec    = 0;
uint32_t t1min     = 0;
uint32_t t3hour    = 0;
byte     celstate  = 0; // initial=0, dialing=1, oncall=2, voice ready=4;
int      stoptimer = 0;
int      stoptemp  = 0;

bool          armed   = false;
volatile byte alarm   = 0;
bool          warmup  = false;
int           temp[4] = {-127, -127, -127, -127};

void dbg(const char* par, const char* val = NULL) {
  Serial.print("["); Serial.print(millis()); Serial.print("]"); Serial.print(par);
  if ( val != NULL ) Serial.print("="), Serial.print(val);
  Serial.println();
}
int getanalog(byte pin) {
  uint16_t _lvl[5];
  for (byte i = 0; i < 5; i++) _lvl[i] = analogRead(pin);
  return find_similar(_lvl, 5, 3);
}
float vbatt() {
  int _lvl = getanalog(BATT_PIN); return(_lvl/65.0);
}
float ibatt() {
  int _lvl = getanalog(CURRENT_PIN); return (_lvl - 640) / 20.46;
}
bool neutral() {
  return(getanalog(NEUTRAL_PIN) < 130); // ~591 for INTERNAL
}
bool engrun() {
  return( fuelpump.active() || (vbatt() > 13.8) );
}
bool drive() {
  return( engrun() && !neutral() );
}
void arming(bool arm) {
  if ( arm ) attachInterrupt(0, shock2, FALLING), attachInterrupt(1, shock1, FALLING);
  else       detachInterrupt(0),                  detachInterrupt(1);
  armed = arm;
}
void shock1() { alarm |= 1; }
void shock2() { alarm |= 0x82; }
void starting() {
  if ( engrun() || !neutral() ) return;
  dbg("starting!"); gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pubf("info/stoptimer", stoptimer, 0), pubf("info/stoptemp", stoptemp, 0), gsm.write(0x1A);
  uint32_t _tinit = 0; float _vrel = 0; detachInterrupt(0); detachInterrupt(1);
  ign.set(true); delay(200);
  if ( starter.active() ) goto _err;                            // mosfet breakdown
  if ( !fuelpump.active() ) goto _err; delay(3000);             // fuelpump fault?  
  _vrel = vbatt() - 2; _tinit = millis();
  if ( !starter.set(true) ) goto _err; delay(500);              // starter fault?
  while ( ((millis() - _tinit) < 3000) && (vbatt() < _vrel) );  // spinup engine - max 3sec
  if ( starter.set(false) ) goto _ok;
  _err: ign.set(false);
  _ok: if (armed) attachInterrupt(0, shock2, FALLING), attachInterrupt(1, shock1, FALLING);
  ign.change();
  delay(3000); warmup = !warmup && engrun();
}

void modemreset () {
  dbg("reset modem...");
  gsm.println("AT+CFUN=1,1");
  if ( gsm.find("OK") ) delay(3500), gsm.println("AT+BTPOWER=1");
  tpingresp = millis();
}
bool atfind(const char* str) {
  return strstr(at, str) != NULL;
}
void play(const char* track) {
  celstate &= ~bit(2);
  gsm.print("AT+CREC=4,\"C:\\User\\"), gsm.print(track), gsm.println(".amr\",0,90");
}
void pub (const char* topic, const char* msg, bool retn = false) { 
  gsm.write(0x30 | (byte)retn);
  gsm.write((2+strlen(topic) + strlen(msg)));
  gsm.write((byte)0x00), gsm.write(strlen(topic)), gsm.write(topic);
  gsm.write(msg);
}
void pubf (const char* topic, float val, int x) {
  char _st[8];
  dtostrf(val, 0, x, _st); pub(topic, _st);
}
void sub (const char* topic) {
  gsm.write(0x82);
  gsm.write(strlen(topic) + 5); 
  gsm.write((byte)0x00); gsm.write(0x01)  ;
  gsm.write((byte)0x00); gsm.write(strlen(topic)); gsm.write(topic);
  gsm.write((byte)0x00);
}
void brokercon () {
  dbg("broker connect...");
  gsm.println("AT+CIPSEND"); if ( !gsm.find(">") ) return;
  gsm.write(0x10);
  gsm.write(4 + 2+strlen(proto) + 2+strlen(cid) + 2+strlen(willt) + 2+strlen(willm) + 2+strlen(user) + 2+strlen(pass));
  gsm.write((byte)0x00); gsm.write(strlen(proto)); gsm.write(proto); gsm.write(0x03); // proto, ver
  gsm.write(0xE6); gsm.write((byte)0x00); gsm.write(0x3C);                            // flags, ka timout | E/C -retain/not
  gsm.write((byte)0x00); gsm.write(strlen(cid));   gsm.write(cid);
  gsm.write((byte)0x00); gsm.write(strlen(willt)); gsm.write(willt);
  gsm.write((byte)0x00); gsm.write(strlen(willm)); gsm.write(willm);
  gsm.write((byte)0x00); gsm.write(strlen(user));  gsm.write(user);
  gsm.write((byte)0x00); gsm.write(strlen(pass));  gsm.write(pass);
  pub("info/online", "1", true);
  sub("cmd/#");
  gsm.write(0x1A);
}
void ping() {
  gsm.println("AT+CIPSEND");
  if ( gsm.find(">") ) gsm.write(0xC0), gsm.write(byte(0x00)), gsm.write(0x1A);
}
void sendbalance(const char* msg) {
  if ( msg == NULL ) return;
  char _bal[10] = ""; byte _end = 67;
  for ( byte i = 35; i < _end; i += 4 )
    if ( msg[i] == 'D' ) strcat(_bal, "-");
    else if ( msg[i] == 'E' ) strcat(_bal, "."), _end = i + 9;
    else strncat(_bal, msg+i, 1);
  strcat(_bal, "\0");
  gsm.println("AT+CIPSEND"); if ( gsm.find('>') ) pub("info/balance", _bal, true), gsm.write(0x1A);
  //dbg(_bal);
}
void sendloc(const char* loc) {
  char* _epos = strchr(loc, ',') + 1;
  char* _npos = strchr(_epos, ',') + 1;
  byte  _elen = _npos - _epos - 1;
  byte  _nlen = strchr(_npos, ',') - _npos;
//  char  _link[64] = "https://www.google.com/maps/place/";
  char _link[24];
  strncat(_link, _npos, _nlen); strcat(_link, ","); strncat(_link, _epos, _elen); strcat(_link, "\0");
  //gsm.println("AT+CIPSEND"); if ( gsm.find('>') ) pub("info/location", _link), gsm.write(0x1A);
  dbg(_link);
}
void ipdhandling(const byte* frame, byte len = 1 ) { //++++++++++++++  PROCESSING DATA FROM BROKER  ++++++++++++++++++
//  for (int i = 0; i < (byte)frame[1]+2; i++) Serial.write(frame[i]);
//  dbg("pack len", itoa(_len));
  tpingresp = millis(); if ( frame == NULL ) return;
  for ( byte _idx = 0; _idx < len; ) {
    if ( (frame[_idx] == 0xD0) && (frame[_idx+1] == 0x00) ) {            // pingresp d0 00
      dbg("ping responce!");
      _idx += 2;
    } else  if ( (frame[_idx] == 0x20) && (frame[_idx+1] == 0x02) ) {    // connak 20 02 00 00
      if ( frame[_idx+3] == 0x00 ) led.act(1000), dbg("conn accepted");
      else { dbg("conn refused"); gsm.println("AT+CIPSHUT"); return; }
      _idx += 4;
    } else if ( (frame[_idx] & ~0x01) == 0x30 ) {                         // pub recv !!sometime 31 10 00 0c
      char* _tfirst = (char*)(frame + _idx + 8);
      byte  _tlen = frame[_idx+3] - 4;
      char* _pfirst = (char*)(frame + _idx + frame[_idx+3] + 4) ;
      byte  _plen = frame[_idx+1] - frame[_idx+3] - 2;
      char  _topic[_tlen+1]; strncpy(_topic, _tfirst, _tlen); _topic[_tlen] = '\0';
      char  _payl [_plen+1]; strncpy(_payl, _pfirst, _plen); _payl[_plen] = '\0';
      _idx += frame[_idx+1] + 2;
      dbg(_topic, _payl);
      if ( strstr(_topic, "stoptimer") != NULL ) {
        stoptimer = atoi(_payl);
      } else if ( strstr(_topic, "stoptemp") != NULL ) {
        stoptemp = atoi(_payl);
      } else if ( strstr(_topic, "start") != NULL ) {
        if ( atoi(_payl) == 1 ) starting();
        else ign.set(false); 
        gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pub("info/warmup", warmup ? "1" : "0"), gsm.write(0x1A);
      } else if ( strstr(_topic, "armed") != NULL ) {
        armed = true;
      } else if ( strstr(_topic, "update") != NULL ) {
        if      ( atoi(_payl) == 2 ) gsm.println("AT+CIPGSMLOC=1,1");
        else if ( atoi(_payl) == 1 ) gsm.println("AT+CUSD=1,\"*105#\"");
        else                         gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) {
          pubf("info/engtemp", temp[0], 0);
          pubf("info/outtemp", temp[1], 0);
          pubf("info/vehtemp", temp[2], 0);
          pubf("info/vbatt",   vbatt(), 2);
          pubf("info/ibatt",   ibatt(), 2);
          pubf("info/stoptemp",  stoptemp,  0);
          pubf("info/stoptimer", stoptimer, 0);
          pub ("info/ign",    ign.active()  ?  "1" : "0");
          pub ("info/eng",    engrun()      ?  "1" : "0");
          pub ("info/warmup", warmup        ?  "1" : "0");
          pub ("info/doorop", door.active() ?  "1" : "0");
          pub ("info/hoodop", hood.active() ?  "1" : "0");
          pub ("info/armed",  armed         ?  "1" : "0");
          gsm.write(0x1A); if ( gsm.find("SEND OK") ) gsm.println("AT+CSQ");
        }                      
      } else if ( strstr(_topic, "horn") != NULL ) {
        siren.act(2000); flash.act(3000);
      }
    } else break; //unexpected header
  } // cycle
}  // ipd func
void athandling() { //++++++++++++++++++ AT HANDLING ++++++++++++++++++++
  byte _atlen = 0;
  while ( gsm.available() ) {
    if ( (_atlen + 1) < sizeof(at) ) at[_atlen++] = gsm.read();
    else gsm.read();
    delay(1);
  } at[_atlen] = '\0';
  for (int i = 0; i < _atlen; i++) Serial.write(at[i]);
  if ( atfind("SMS Ready") )    gsm.println("AT+CIPHEAD=1;+CIPSHUT");
  if ( atfind("SHUT OK") )      gsm.print("AT+CIPSTART=TCP,"), gsm.println(broker);
  if ( atfind("CONNECT OK") )   brokercon();
  if ( atfind("DEACT")
    || atfind("CLOSED")
    || atfind("CONNECT FAIL") ) dbg("conn fail!"), gsm.println("AT+CIPSHUT");
  if ( atfind("ERROR") )        dbg("ERR_STR", at)/*/, modemreset()*/;
    
  if ( atfind("+CLIP:") ) if ( atfind("\"admin") ) {                // cellular bits:
    siren.set(false); flash.set(false);                             // 0( 1 ) = dialing
    gsm.println("ATA"); celstate = 6; delay(500); play("hello");    // 1( 2 ) = on call
  } else gsm.println("ATH0");                                       // 2( 4 ) = voice ready
  if ( atfind("+COLP:") ) {
    siren.set(false); flash.set(false);
    celstate = 6; delay(500); play("hello");
  }
  if ( atfind("+CREC: 0") ) celstate |= bit(2);
  if ( atfind("NO CARRIER") || atfind("BUSY") || atfind("NO ANSWER") ) tpingresp = millis(), celstate = 0;
  if ( atfind("+DTMF: #") ) { alarm = 0; if (celstate == 6) play("alarmres"); }
  if ( atfind("+BT") && atfind(btkey) ) if ( !drive() ) arming( atfind("DISCONN") );
  if ( atfind("+CUSD:") ) sendbalance(strstr(at, "+CUSD:") + 11);
  if ( atfind("+CSQ:") ) { gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pubf("info/sq", atoi(strstr(at, "+CSQ:")+6), 0), gsm.write(0x1A); }
  if ( atfind("+IPD") )   ipdhandling( strchr(strstr(at, "+IPD"), ':') + 1, atoi(strchr(strstr(at, "+IPD"), ',') + 1) );
  if ( atfind("+CIPGSMLOC:") )  sendloc(strstr(at, "+CIPGSMLOC:") + 12);
}
void dsinit() {
  for( byte _i = 0; _i < sizeof(temp)/sizeof(int); _i++ ) {
    ds.reset(); ds.select(sid[_i]);
    ds.write(0x4E); ds.write(0x7F), ds.write(0xFF); ds.write(0x1F);
  //  ds.reset(); ds.select(sid[_i]); ds.write(0x48); // to rom
  }  
}
void updtemps() {
  for( byte _i = 0; _i < sizeof(temp)/sizeof(int); _i++ ) {
    ds.reset(); ds.select(sid[_i]); ds.write(0x44); delay(100);
    ds.reset(); ds.select(sid[_i]); ds.write(0xBE);
    int16_t _raw = ds.read(); _raw |= ds.read() << 8; _raw >>= 4;
    ds.read(); ds.read(); // th/tl
    temp[_i] = (ds.read() == 0x1F) ? (int)_raw : -127; // conf?
  } ds.reset();
}

void setup() {
  pinMode(SHOCK1_PIN, INPUT_PULLUP); pinMode(SHOCK2_PIN, INPUT_PULLUP);
  Serial.begin(9600); delay(200);
  gsm.begin(9600); delay(200);
  dsinit(); updtemps();
  modemreset();
}

void loop() {
  if ( gsm.available() ) athandling();
  led.set( armed && ((millis() & 0x3ff) > 0x370) );
  if ( drive() ) dvr.act(60000);
  if ( ((millis() - tpingresp) > 70000) && (celstate == 0) ) dbg("broker isn't responding!"), modemreset();
  if ( (millis() - t30sec) > 30000 ) t30sec = millis(), updtemps(), ping(); 
  if ( warmup ) if ( (millis() - t1min) > 60000 ) { 
    t1min = millis(); if ( stoptimer > 1 ) stoptimer--;
    gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) {
      pubf("info/stoptimer", stoptimer, 0);
      pubf("info/stoptemp", stoptemp, 0);
      pubf("info/engtemp", temp[0], 0);
      pubf("info/ibatt", ibatt(), 2);      
      gsm.write(0x1A);
    }
  }
  if ( (millis() - t3hour) > 10800000 ) t3hour = millis(), gsm.println("AT+CUSD=1,\"*105#\"");
  if ( warmup ) if ( (temp[0] > stoptemp) || (stoptimer < 1) || (ibatt() > 15.0) || !neutral() ) {
    ign.set(false); warmup = false;
    gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) {
      pub ("info/warmup", "0");
      pubf("info/ibatt", ibatt(), 2);      
      gsm.write(0x1A);
    }
  }
  switch( lock.change() ) { //csan locking 
    case 0:
      arming(false); break;
    case 1:
      //if ( drive() ) break;
      if ( door.active() || hood.active() ) siren.act(200);
      arming(true);
  }
  if ( armed ) {
    if ( hood.change() == 1 ) alarm |= 0x84;
    if ( door.change() == 1 ) alarm |= 0x88;
    if ( ign.change()  == 1 ) alarm |= 0x90;
  } if ( (temp[1] > 50) || (temp[2] > 50) || (temp[3] > 50) ) alarm |= 0xA0;
  //dbg("alarm", alarm);
  if ( alarm == 1 ) {
    static bool _even = false; 
    siren.act(500); flash.act(2000); dvr.act(30000);
    gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pub("notify", _even ? "kick!" : "kick! "), gsm.write(0x1A);
    alarm &= ~1; _even = !_even;
  } else if ( alarm > 0x81 ) {
    siren.act(20000); flash.act(20000); dvr.act(60000);
    alarm &= ~bit(7);
    if ( celstate == 0 ) gsm.println("ATD>\"admin\";"), celstate = 1;
  }
  if ( (alarm > 1) && (celstate == 6) )
    for ( byte _i = 5; _i > 0; _i-- ) {           //  alarm bits: 
      if ( (alarm & bit(_i)) == 0 ) continue;     //  0( h01 ) = shock1
      alarm &= ~bit(_i);                          //  1( h02 ) = shock2
      if ( _i == 5 ) { play("fire");     break; } //  2( h04 ) = hood open
      if ( _i == 4 ) { play("ignon");    break; } //  3( h08 ) = door open
      if ( _i == 3 ) { play("dooropen"); break; } //  4( h10 ) = ignition on
      if ( _i == 2 ) { play("hoodopen"); break; } //  5( h20 ) = fire
      if ( _i == 1 ) { play("shock");    break; } //  7( h80 ) = NEW IMPORTANT ALARM
  }
  dvr.processing(); siren.processing(); flash.processing(); led.processing();
} // ************* LOOP +++++++++++++++++++++++
.//++++++++++ classes.h+++++++++++++++++
class Input {
  public:
    Input(byte pin) {
      _pin = pin;
      pinMode(_pin, INPUT_PULLUP);
      _old = active();
    }
    bool active(void) {
      byte _cntr; do {
        _cntr = 0;
        for ( byte _i = 0; _i < 10; _i++ ) _cntr += (byte)digitalRead(_pin);
      } while ( (_cntr > 0) && (_cntr < 10) );
      return _cntr == 0;
    }
    int change() {
      bool _state = active();
      if (_state == _old) return -1;
      _old = _state;
      return (int)_state;
    }
  private:
    byte  _pin; bool _old;
}; // Input

class Output {
  public:
    Output(byte pin) {
      _pin = pin;
      pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW);
    }
    void set(bool val) {
      digitalWrite(_pin, val ? HIGH:LOW);
      _state = val;
      _actual = false;
    }
    void act(uint32_t timeout) {
      _begin = millis();
      _timeout = timeout;
      _actual = true;
    }
    void processing() {
      if (_actual) {
        bool _timely = (millis() - _begin) < _timeout;
        if (_timely && !_state) { digitalWrite(_pin, HIGH); _state = true;}
        if (!_timely && _state) { digitalWrite(_pin, LOW); _state = false; _actual = false; }
      }        
    }
  private:
    byte _pin;
    uint32_t _begin = 0;
    uint32_t _timeout = 0;
    bool _actual = false;
    bool _state = false;
}; // Output

class InOut : public Input, Output {
  public:
    InOut(byte inpin, byte outpin) : Input(inpin), Output(outpin) { }
    bool set(bool val) {
      Output::set(val);
      return (active() == val);
    }
}; // InOut
//++++++++++++++ consts.h  +++++++++++++++++
//============ pins ==============
#define IGN_PIN              4  // включение зажигания - транспондер через оптрон (2)
#define STARTER_PIN          5  // включение стартера (3)
#define SIREN_PIN            6  // сирена (4)mqtt
#define DVR_PIN              7  // видеоргистратор (5)
#define IGN_SUPPLY_PIN      A5  // контроль зажигания (6)
#define FLASH_PIN            8  // аварийка (7)
#define SIM800RX_PIN         9  // RX Arduino (TX sim800L) (8)
#define SIM800TX_PIN        10  // TX Arduino (RX sim800L) (9)
#define FUELPUMP_PIN        11  // контроль работы бензонасоса ! (оптрон) 10
#define STARTER_SUPPLY_PIN  A4  // контроль питания стартера ! (оптрон) (11)
#define ONEWIRE_PIN         12  // датчики температуры
#define LED_PIN             13  // светодиод
#define HOOD_PIN            A0  // концевик дверей (через диод) PULLUP
#define DOOR_PIN            A1  // концевик капота (через диод) PULLUP
#define NEUTRAL_PIN         A2  // контроль нейтрали ! (через диод) PULLUP
#define LOCK_PIN            A3  // центральный замок (через диод) PULLUP
#define SHOCK1_PIN           3  // датчик удара1 (через диод) PULLUP (A4)
#define SHOCK2_PIN           2  // датчик удара2 (через диод) PULLUP (A5)
#define BATT_PIN            A7  // напряжение аккума (делитель)
#define CURRENT_PIN         A6  // ток в цепи +12В

const char*  broker   = "m23.cloudmqtt.com,17510"; // addr,port
const char*  proto    = "MQIsdp";
const char*  cid      = "BlackBox";
const char*  willt    = "info/online";
const char*  willm    = "0";
const char*  user     = "sdfwevebd";
const char*  pass     = "4t5g4tgefg3rgrg";

const char*  btkey  = "CONN: \"Redmi\",20:ca:2e:ff:55:4a";

const byte sid[4][8] = { {0x28, 0x7B, 0x45, 0x46, 0x92, 0x01, 0x02, 0xB3},   // engine
                         {0x28, 0xEB, 0xB0, 0x77, 0x91, 0x0D, 0x02, 0x18},   // outdoor
                         {0x28, 0x7E, 0x60, 0x46, 0x92, 0x02, 0x02, 0x27},   // vehacle
                         {0x28, 0xE6, 0xBD, 0x3B, 0x05, 0x00, 0x00, 0xCF} }; // self 

 

sadman41
Offline
Зарегистрирован: 19.10.2016
Алексей.
Алексей. аватар
Offline
Зарегистрирован: 02.02.2018

ЕвгенийП пишет:

vlad072 пишет:

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

И не подумает. Вот даже в мыслях у него не будет.

Дык эта шутка такая ;)))
Если бы ни разу не приходилось менеджер памяти допиливать, то можно бы уточнить откуда такие сведения о компиляторе, а так просто поржать.

b707
Онлайн
Зарегистрирован: 26.05.2017

vlad072 пишет:

b707 пишет:

Строки во флеш класть не пробовали?

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

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

Код весьма кудряво написан. Сами с нуля писали или правите то, что нашли в инете?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

свой код и прямо таки с паролями выложили )))

andycat
andycat аватар
Онлайн
Зарегистрирован: 07.09.2017

vlad072  , примеров и добрых советов вы как я понял слушать не желаете как я понял,

было же вам уже с progmem пример - чем не нравится то?

http://arduino.ru/forum/programmirovanie/snova-mqtt-1?page=1#comment-428950

 

vlad072
Offline
Зарегистрирован: 01.08.2017

sadman41 Спасибо, теперь многое становится понятно.

"Несмотря на указание const при декларации констант, компилятор все равно для их хранения использует ОЗУ (при старте программы они просто копируются из flash в RAM). "

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

andycat пишет:

примеров и добрых советов вы как я понял слушать не желаете

"Нет ничего более раздражающего, чем хороший пример" (Марк Твен).

Green
Онлайн
Зарегистрирован: 01.10.2015

ua6em пишет:

а 0x0000 ? надеюсь здесь он тоже вниз растёт?

Вниз по кругу.)