Vcc & Temperature read & sleep

gmurvs
Offline
Зарегистрирован: 15.04.2014
#in clude  <avr/sleep.h>
#include  <avr/wdt.h>


#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC
#define adc_enable()  (ADCSRA |=  (1<<ADEN)) // re-enable ADC

#define s025 0b000100


const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 150;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  byte myvccInByte;
  long myvcc;
  int myTemp;

  adc_enable();
  myvcc = readVcc();
  myvccInByte = myvcc / 100;
  showSignal(myvccInByte);

  myWatchdogEnable(0b100000); //4 s

  adc_enable();
  myTemp = readTemp();

  if (myTemp < 0) {
    procMinus();
  }
  showSignal(myTemp);


  myWatchdogEnable(0b100001); //8 s
  myWatchdogEnable(0b000111); //2 s
}

void myWatchdogEnable(const byte interval)
{
  // sleep bit patterns:
  //  1 second:  0b000110
  //  2 seconds: 0b000111
  //  4 seconds: 0b100000
  //  8 seconds: 0b100001
  //0,25 seconds: 0b000100

  adc_disable();

  // clear various "reset" flags
  MCUSR = 0;
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval
  WDTCSR =  0b01000000 | interval;// set WDIE, and delay
  wdt_reset();  // pat the dog

  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS);
  sleep_cpu ();

  // cancel sleep as a precaution
  sleep_disable();
}


ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

long readVcc() {
  int Prior_ADMUX;
  Prior_ADMUX = ADMUX;
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0) ;
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

  delay(75); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both

  long result = (high << 8) | low;

  ADMUX = Prior_ADMUX;
  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}


void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      myWatchdogEnable(s025);
      proc0();
      break;
    case 3:
      proc1();
      myWatchdogEnable(s025);
      proc1();
      break;
    case 4:
      proc1();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc0();
      break;
    case 5:
      proc1();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc1();
      break;
    case 6:
      proc1();
      myWatchdogEnable(s025);
      proc1();
      myWatchdogEnable(s025);
      proc0();
      break;
    case 7:
      proc1();
      myWatchdogEnable(s025);
      proc1();
      myWatchdogEnable(s025);
      proc1();
      break;
    case 8:
      proc1();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc0();
      break;
    case 9:
      proc1();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc0();
      myWatchdogEnable(s025);
      proc1();
      break;
  }
}

void procL() {
  digitalWrite(13, HIGH);
  delay(50);
  digitalWrite(13, LOW);
}

void procMinus() {
  digitalWrite(13, HIGH);
  delay(5000);
  digitalWrite(13, LOW);
}


void proc0() {
  digitalWrite(13, HIGH);
  delay(DURATION_0);
  digitalWrite(13, LOW);
}

void proc1() {
  digitalWrite(13, HIGH);
  delay(DURATION_1);
  digitalWrite(13, LOW);
}


void showSignal(byte ssgnl) {
  String beaconData = String(ssgnl);
  String oneStr = "";

  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);

    myWatchdogEnable(0b000110);

    oneStr = "";
  }
}


int readTemp(void)
{
  unsigned int wADC;
  double t;

  // The internal temperature has to be used
  // with the internal reference of 1.1V.
  // Channel 8 can not be selected with
  // the analogRead function yet.

  // Set the internal reference and mux.
  ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
  ADCSRA |= _BV(ADEN);  // enable the ADC

  delay(20);            // wait for voltages to become stable.

  ADCSRA |= _BV(ADSC);  // Start the ADC

  // Detect end-of-conversion
  while (bit_is_set(ADCSRA, ADSC));

  // Reading register "ADCW" takes care of how to read ADCL and ADCH.
  wADC = ADCW;

  // The offset of 324.31 could be wrong. It is just an indication.
  t = (wADC - 324.31 ) / 1.22;

  // The returned temperature is in degrees Celsius.
  return (t);
}

 

gmurvs
Offline
Зарегистрирован: 15.04.2014

Полученные значения параметров промаргиваем светодиодом.

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

Автор, вы что сказать-то хотели?

gmurvs
Offline
Зарегистрирован: 15.04.2014

Ничего больше, чем уже сказано. Возможно, кому пригодится для своих задач (я знаю минимум одного такого человека). Я потратил некоторое время на поиск рабочих кодов по данной теме, зачем его еще тратить?

arduinec
Offline
Зарегистрирован: 01.09.2015

gmurvs пишет:

Ничего больше, чем уже сказано. Возможно, кому пригодится для своих задач (я знаю минимум одного такого человека). Я потратил некоторое время на поиск рабочих кодов по данной теме, зачем его еще тратить?

Эти и другие нестандартные возможности Ардуин реализованы здесь: http://arduino.ru/forum/programmirovanie/sysinfo-arduino

gmurvs
Offline
Зарегистрирован: 15.04.2014

Спасибо, буду изучать