Conflitto ATTiny84, SoftwareSerial e interrupt

Buongiorno a tutti;
Ho un arduino nano (master) che tramite un modulo HC-12 e 4 pulsanti invia comandi ai dispositivi slave (sensori finestre) e funziona correttamente.

L'hardware dello slave è questo:
Modulo 4056 per la carica della batteria
ATTiny84 1MHz (ATTiny-Core)
Buzzer pilotato da un transistor bc547 e diodo di protezione
Contatto reed
Modulo HC-12 (FU2, B1200)
Connettore SPI per gli aggiornamenti

Con la versione base del codice tutto funziona e lo slave alimentato con una batteria 18650 3.7V 2200 mA ha un consumo energetico di 2.5 mA
voglio ridurre il consumo e aggiungo al codice il deep sleep e il consumo si riduce a 0.5 mA (fantastico) eseguo i test e noto che riceve e invia i dati tramite HC-12 correttamente, come fa a funzionare se è in deep sleep? e perché il resto del codice nel loop() non funziona più?.
Ho provato ad inserire un'interrupt che si attiva al cambio di stato del contatto reed ma purtroppo va in conflitto con la SoftwareSerial, ho provato neoSWSerial, AltSoftSerial ma per le mie limitate conoscenze non sono riuscito a farle funzionare.
prima di scrivere qui ho passato 2 giorni a dialogare con l'AI di Copilot e Gemini ma non c'è stato niente da fare quindi ho deciso di chiedere a voi.
il codice che allego è la versione con deep sleep ma senza interrupt, chiedo a voi un grande aiuto.
Amedeo Di Vito
hc12_slave.ino (4.3 KB)

Mi dispiace non poterti aiutare, non ho conoscenze nella direzione che ti interessa

rimango però qui in ascolto, chissà mai

comunque, si può vedere il codice della parte interrupt (che hai omesso)?

Non metterlo come file.ino, non riesco a vederlo dal furbofono
mettilo in chiaro nel messaggio

Grazie

questo è il codice con interrupt

#include <Arduino.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>  
#include <SoftwareSerial.h>

// Definizioni dei pin
#define REED_PIN 0
#define ALARM_ON 10
#define LED_PIN 3
#define HC12_SET_PIN 7
#define HC12_RX_PIN PA2  
#define HC12_TX_PIN PA1  

// Inizializzazione della seriale software
SoftwareSerial hc12(HC12_RX_PIN, HC12_TX_PIN);

// Variabili globali
volatile bool wakeUpFlag = false;  // Flag per gestione wake-up
bool enabled = false;
bool alarmActive = false;
unsigned long timerVolt;
const float LOW_BATT = 3.0;
uint8_t device = 1;
uint8_t delayRead = 100;
uint8_t delayAlarm = 100;

void setup() {
  // Inizializzazione della comunicazione seriale
  hc12.begin(1200);

  // Configurazione dei pin
  pinMode(ALARM_ON, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(REED_PIN, INPUT_PULLUP);
  pinMode(HC12_SET_PIN, OUTPUT);
  digitalWrite(HC12_SET_PIN, HIGH);

  // Indicazione di avvio
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  digitalWrite(LED_PIN, LOW);

  // Pulizia del buffer seriale
  clearBuffer();

  // Inizializzazione del timer per il controllo della tensione
  timerVolt = millis();
  checkVolt();

  // Configura l'interrupt per il REED switch (Pin Change Interrupt)
  PCMSK0 |= (1 << PCINT0);  // Abilita l'interrupt sul REED_PIN (PA0)
  GIMSK |= (1 << PCIE0);    // Abilita il Pin Change Interrupt
  sei();                    // Abilita gli interrupt globali
}

ISR(PCINT0_vect) {
  wakeUpFlag = true;  // Imposta il flag di risveglio
}

void loop() {
  // Controllo del wake-up
  if (wakeUpFlag) {
    wakeUpFlag = false;  // Resetta il flag

    if (enabled) {
      alarmActive = true;
      beep(3);  // Emesso un segnale acustico di allarme
    }
  }

  // Gestione dell'allarme
  if (alarmActive) {
    digitalWrite(ALARM_ON, HIGH);
    delay(delayAlarm);
    digitalWrite(ALARM_ON, LOW);
    delay(delayAlarm);
  } else {
    digitalWrite(ALARM_ON, LOW);
  }

  // Controllo della batteria ogni 5 minuti
  if (millis() - timerVolt > 300000L) {
    timerVolt = millis();
    checkVolt();
  }

  // Lettura dei dati dalla seriale
  if (hc12.available() > 0) {
    dataRead();
  }

  // Modalità sleep per risparmiare energia
  enterSleepMode();
}

void enterSleepMode() {
  cli();  // Disabilita gli interrupt per preparare il sonno
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei();  // Riabilita gli interrupt globali
  sleep_mode();  // Entra in modalità sleep
  sleep_disable();  // Ritorna qui dopo il wake-up
}

void dataRead() {
  char cmd;
  char dev;
  char buf[3];
  if (hc12.available() > 0) {
    cmd = hc12.read();
    delay(delayRead);
    if (cmd != '#') {
      clearBuffer();
      return;
    }
    dev = hc12.read();
    delay(delayRead);
  }

  if ((uint8_t)dev == device + 48) {
    clearBuffer();
    if (enabled) {
      enabled = false;
      alarmActive = false;
      beep(2);
    } else {
      enabled = true;
      beep(1);
    }
    sprintf(buf, "%d%d", device, enabled);
    hc12.println(buf);
  }
}

void clearBuffer() {
  while (hc12.available() > 0) {
    hc12.read();
  }
}

void beep(uint8_t num) {
  for (int i = 0; i < num; i++) {
    digitalWrite(ALARM_ON, HIGH);
    delay(20);
    digitalWrite(ALARM_ON, LOW);
    delay(80);
  }
}

void checkVolt() {
  float batteryVoltage = readVcc();
  if (batteryVoltage <= LOW_BATT) {
    digitalWrite(LED_PIN, HIGH);
  } else {
    digitalWrite(LED_PIN, LOW);
  }
}

float readVcc() {
  ADMUX = _BV(MUX5) | _BV(MUX0);  
  delay(2);                       
  ADCSRA |= _BV(ADSC);            
  while (bit_is_set(ADCSRA, ADSC));
  uint16_t low = ADCL;
  uint8_t high = ADCH;
  long vcc = (high << 8) | low;
  return (1125300.0 / vcc) / 1000.0;
}

Non posso prometterti nulla

Ma domani ci guardo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.