/*================================================================================================*/
#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 = ⅅ
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];
}