Автономное питание маломощных изделий

andrey1933

✩✩✩✩✩✩✩
26 Дек 2019
9
0
Ребята как вы питаете свои автономные изделия на ардуино? столкнулся внезапно с проблемой, что нет идеального источника питания для меня.
Имеем ардуино mini, сенсоры, радиопередатчик, . все на 5 V . Ардуино иногда просыпается, смотрит датчики, посылает по радиоканалу. Сенсоры и радиомодуль отключаются мосфетом. Температура комнатная. И тут возникла проблема для меня, что нет подходящих аккумуляторов, слишком токи малые для некоторый, или продолжительность работы, для других надо ставить преобразователь напряжения, что не ах. Как ни странно батарейки самое то, но не нравиться одноразовое использовать - экология ) да и в итоге дороже будет.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,242
1,297
Москва
на левой фото автономный регистратор температуры, с заданным интервалом заданное число раз считывает температуру и пишет в EEPOM , в промежутках глубокий сон. на 3-ое суток батарейки хватает. Больше не пробовал
 

andrey1933

✩✩✩✩✩✩✩
26 Дек 2019
9
0
на левой фото автономный регистратор температуры, с заданным интервалом заданное число раз считывает температуру и пишет в EEPOM , в промежутках глубокий сон. на 3-ое суток батарейки хватает. Больше не пробовал
спасибо! только не понял . а батарея - аккумулятор robition Li-Po на 3.7 в? а можно скетч посмотреть?
 

andrey1933

✩✩✩✩✩✩✩
26 Дек 2019
9
0
3.
на левой фото автономный регистратор температуры, с заданным интервалом заданное число раз считывает температуру и пишет в EEPOM , в промежутках глубокий сон. на 3-ое суток батарейки хватает. Больше не пробовал
и 3.7 V конечно маловато..придется тогда извращаться с частотой ардуины
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,242
1,297
Москва
C++:
/*================================================================================================*/
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <OneWire.h>
#include <TinyWireM.h>
/*================================================================================================*/
struct HeaderRom
{
  byte TermAdress[8] = {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7};  
  uint32_t EEPROMmem = 0;
  uint16_t EEPROMbase = 0;
  uint16_t MeasureNum = 0;
  byte WatchDogDelay = 0;   
  uint16_t MeasureInt = 0; 
  byte BlinckTime = 0; 
};

struct WorkHeader
{
  uint16_t MeasureNum = 0;
  uint16_t MeasureInt = 0;    
  byte BlinckTime = 0;           пробуждение.
};
/*================================================================================================*/
const byte rom = 0x50;
HeaderRom SetupVars;
WorkHeader WorkVars;
void *PSetupVars;
#define TERM_PIN 3
#define LED_PIN 4
#define BUFFER_LENGTH 32
/*================================================================================================*/
void setup() {
  pinMode(LED_PIN, OUTPUT);           

  TinyWireM.begin();                  
  LED_UP_DOWN(2, 0);              
  LED_UP_DOWN(2, 1);              
  delay(500);                        
  TinyWireM.beginTransmission(rom);   
  byte error = TinyWireM.endTransmission();
  if (error != 0)  
  {
    LED_QIUCK(2);                     
    LED_SLOW(2);
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_mode();                     
  };

  PSetupVars = &SetupVars; 
  readEEPROM(rom, 0, PSetupVars, sizeof(SetupVars));   


  byte addr[8];                       
  OneWire  DalasTemp(TERM_PIN);
  DalasTemp.reset_search();
  delay(250);
  if ( !DalasTemp.search(addr))
  {
    LED_SLOW(2);                      
    LED_QIUCK(1);
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_mode();                     
  };


  if (!CompTD(SetupVars.TermAdress, addr))  
  {
    MyWriteData(rom, 0, addr, sizeof(addr), 32);
    readEEPROM(rom, 0, PSetupVars, sizeof(SetupVars));
  };


}
/*================================================================================================*/
void loop() {

  if ((SetupVars.BlinckTime > 0) && (WorkVars.BlinckTime == 0))
  {
    LED_QIUCK(1);
  };
  WorkVars.BlinckTime = Test_n_Mod_Predel(WorkVars.BlinckTime, SetupVars.BlinckTime);

  if (WorkVars.MeasureInt == 0)
  {

    int16_t DD = Get_Dallas_data(SetupVars.TermAdress, TERM_PIN);
    void *pp;
    pp = &DD;
    MyWriteData(rom, SetupVars.EEPROMbase + (WorkVars.MeasureNum * 2), pp, sizeof(DD), 32);

    if (SetupVars.BlinckTime == 255) LED_SLOW(1);
    WorkVars.MeasureNum++;
  };
  WorkVars.MeasureInt = Test_n_Mod_Predel(WorkVars.MeasureInt, SetupVars.MeasureInt);


  if (WorkVars.MeasureNum < SetupVars.MeasureNum)
  {
    myWatchdogEnable(SetupVars.WatchDogDelay); // установка пробуждения
  }
  else
  {
    LED_UP_DOWN(4, 1); //сигнал о том, что работа выполнена.
  };

  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_mode();                     
}
/*================================================================================================*/
ISR(WDT_vect)
{
  wdt_disable();  // disable watchdog
}
/*================================================================================================*/
void myWatchdogEnable(byte interval)
{
  // if (interval > 7) interval = interval + 24;
  interval = 0b100001;
  MCUSR = 0;
  WDTCR |= 0b00011000;
  WDTCR =  0b01000000 | interval;
  wdt_reset();
};
/*================================================================================================*/
void LED_UP_DOWN(byte dl, byte n)
{
  for (int i = 0; i != 255; i++)
  {
    if (n == 0) analogWrite(LED_PIN, i);
    else analogWrite(LED_PIN, 255 - i);
    delay(dl);
  }
}
/*================================================================================================*/
void LED_QIUCK(byte n)
{
  for (int i = 0; i < n; i++)
  {
    digitalWrite(LED_PIN, HIGH);  //если памяти нет, то 4 раза мигаем
    delay(100);
    digitalWrite(LED_PIN, LOW);
    delay(100);
  }
}
/*================================================================================================*/
void LED_SLOW(byte n)
{
  for (int i = 0; i < n; i++)
  {
    digitalWrite(LED_PIN, HIGH);  //если памяти нет, то 4 раза мигаем
    delay(500);
    digitalWrite(LED_PIN, LOW);
    delay(500);
  }
}
/*================================================================================================*/
byte readEEPROM (byte device, unsigned int addr, byte * data, byte len )
{
  byte err;
  byte counter;

  if (len > BUFFER_LENGTH)  // 32 (in Wire.h)
    return 0xFF;  // too long

  TinyWireM.beginTransmission (device);
  TinyWireM.write ((byte) (addr >> 8));    // high order byte
  TinyWireM.write ((byte) (addr & 0xFF));  // low-order byte
  err = TinyWireM.endTransmission ();

  if (err != 0)
    return err;  // cannot read from device

  // initiate blocking read into internal buffer
  TinyWireM.requestFrom (device, len);

  // pull data out of Wire buffer into our buffer
  for (counter = 0; counter < len; counter++)
  {
    data [counter] = TinyWireM.read ();
  }

  return 0;  // OK
}  // end of readEEPROM
/*------------------------------------------------------------------------------------------------*/
// read one byte from device, returns 0xFF on error
byte readEEPROM (byte device, unsigned int addr )
{
  byte temp;

  if (readEEPROM (device, addr, &temp, 1) == 0)
    return temp;

  return 0xFF;

}  // end of readEEPROM
/*================================================================================================*/
bool CompTD(byte a1[8], byte a2[8])
{
  for (int i = 0; i < 8; i++) {
    if (a1[i] != a2[i]) return false;
  }
  return true;
}
/*================================================================================================*/
uint16_t Test_n_Mod_Predel(uint16_t Val, uint16_t MaxVal)
{
  if ((Val + 1) >= MaxVal) return 0;
  else return Val + 1;
};
/*================================================================================================*/
byte Test_n_Mod_Predel(byte Val, byte MaxVal)
{
  if ((Val + 1) >= MaxVal) return 0;
  else return Val + 1;
};
/*================================================================================================*/
void MyWriteDataByByte(byte device, unsigned int addr, byte * data, byte len )
{
  for (int i = 0; i < len; i++)
  {
    TinyWireM.beginTransmission(device);
    TinyWireM.write((int)((addr + i) >> 8));
    TinyWireM.write((int)((addr + i) & 0xFF));
    TinyWireM.write(data[i]);
    TinyWireM.endTransmission();
    delay(10);
  };
}
/*================================================================================================*/
void MyWriteData(byte device, unsigned int addr, byte * data, byte len, byte mpage )
{
  uint16_t p1, p2;
  p1 = addr / mpage;
  p2 = (addr + len - 1) / mpage;
  if (p1 == p2)
  {
    TinyWireM.beginTransmission(device);
    TinyWireM.write((int)(addr >> 8));
    TinyWireM.write((int)(addr & 0xFF));
    TinyWireM.write(data, len);
    TinyWireM.endTransmission();
    delay(10);
  }
  else
  {
    int lmal = p2 * mpage - addr;
    TinyWireM.beginTransmission(device);
    TinyWireM.write((int)(addr >> 8));
    TinyWireM.write((int)(addr & 0xFF));
    TinyWireM.write(data, lmal);
    TinyWireM.endTransmission();
    delay(10);

    TinyWireM.beginTransmission(device);
    TinyWireM.write((int)((p2 * mpage) >> 8));
    TinyWireM.write((int)((p2 * mpage) & 0xFF));
    TinyWireM.write(&data[lmal], len - lmal);
    TinyWireM.endTransmission();
    delay(10);

  };
}
/*================================================================================================*/
uint16_t Get_Dallas_data(byte addr[8], byte pin)
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  OneWire  ds(pin);

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);
  delay(1000);
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }
  return (data[1] << 8) | data[0];
}