Errore su Attiny ma non su NANO

Ho comperato delle nuove sonde umidità e temperatura AHT25.
Su Nano non ho problemi, uso la libreria AHTxx che comprende anche la serie AHT20 e che è prevista per il Core di Spencer Konde.
Solo che su Attiny85, quando carico l'esempio AHT20_Serial, mi da questo errore:

C:\MEGA\sketchbook\libraries\AHTxx-main\src\AHTxx.cpp: In member function 'bool AHTxx::begin(uint32_t, uint32_t)':
C:\MEGA\sketchbook\libraries\AHTxx-main\src\AHTxx.cpp:95:8: error: 'class TwoWire' has no member named 'setWireTimeout'
   Wire.setWireTimeout(stretch, false);                     //experimental! default 25000usec, true=Wire hardware will be automatically reset on timeout
        ^~~~~~~~~~~~~~
exit status 1
Errore durante la compilazione per la scheda ATtiny85 (Micronucleus / DigiSpark).

Se invece rimetto Nano come Scheda, l'errore sparisce ed il programma funziona...

Il programma è questo:

/***************************************************************************************************/
/*
   This is an Arduino example for Aosong ASAIR AHT10/AHT15/AHT20/AHT21/AHT25/AM2301B/AM2311B
   Digital Humidity & Temperature Sensor

   written by : enjoyneering
   sourse code: https://github.com/enjoyneering/

   Aosong ASAIR AHT1x/AHT2x features:
   - AHT1x +1.8v..+3.6v, AHT2x +2.2v..+5.5v
   - AHT1x 0.25uA..320uA, AHT2x 0.25uA..980uA
   - temperature range -40C..+85C
   - humidity range 0%..100%
   - typical accuracy T +-0.3C, RH +-2%
   - typical resolution T 0.01C, RH 0.024%
   - normal operating range T -20C..+60C, RH 10%..80%
   - maximum operating rage T -40C..+80C, RH 0%..100%
   - response time 8..30sec*
   - I2C bus speed 100KHz..400KHz, 10KHz recommended minimum
     *measurement with high frequency leads to heating
      of the sensor, must be > 2 seconds apart to keep
      self-heating below 0.1C

   This device uses I2C bus to communicate, specials pins are required to interface
   Board:                                    SDA              SCL              Level
   Uno, Mini, Pro, ATmega168, ATmega328..... A4               A5               5v
   Mega2560................................. 20               21               5v
   Due, SAM3X8E............................. 20               21               3.3v
   Leonardo, Micro, ATmega32U4.............. 2                3                5v
   Digistump, Trinket, ATtiny85............. PB0              PB2              5v
   Blue Pill, STM32F103xxxx boards.......... PB9/PB7*         PB8/PB6*         3.3v/5v
   ESP8266 ESP-01........................... GPIO0**          GPIO2**          3.3v/5v
   NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2         GPIO5/D1         3.3v/5v
   ESP32.................................... GPIO21/D21       GPIO22/D22       3.3v
                                             *hardware I2C Wire mapped to Wire1 in stm32duino
                                              see https://github.com/stm32duino/wiki/wiki/API#i2c
                                            **most boards has 10K..12K pullup-up resistor
                                              on GPIO0/D3, GPIO2/D4/LED & pullup-down on
                                              GPIO15/D8 for flash & boot

   Frameworks & Libraries:
   ATtiny  Core - https://github.com/SpenceKonde/ATTinyCore
   ESP32   Core - https://github.com/espressif/arduino-esp32
   ESP8266 Core - https://github.com/esp8266/Arduino
   STM32   Core - https://github.com/stm32duino/Arduino_Core_STM32


   GNU GPL license, all text above must be included in any redistribution,
   see link for details  - https://www.gnu.org/licenses/licenses.html
*/
/***************************************************************************************************/

#include <Wire.h>
#include <AHTxx.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#endif

float ahtValue;                               //to store T/RH result

AHTxx aht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR); //sensor address, sensor type



/**************************************************************************/
/*
    setup()

    Main setup
*/
/**************************************************************************/
void setup()
{
  #if defined(ESP8266)
  WiFi.persistent(false);  //disable saving wifi config into SDK flash area
  WiFi.forceSleepBegin();  //disable AP & station by calling "WiFi.mode(WIFI_OFF)" & put modem to sleep
  #endif

  Serial.begin(115200);
  Serial.println();
  
  while (aht20.begin() != true) //for ESP-01 use aht20.begin(0, 2);
  {
    Serial.println(F("AHT2x not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free

    delay(5000);
  }

  Serial.println(F("AHT20 OK"));

  //Wire.setClock(400000); //experimental I2C speed! 400KHz, default 100KHz
}


/**************************************************************************/
/*
    loop()

     Main loop
*/
/**************************************************************************/
void loop()
{
  /* DEMO - 1, every temperature or humidity call will read 6-bytes over I2C, total 12-bytes */
  Serial.println();
  Serial.println(F("DEMO 1: read 12-bytes"));

  ahtValue = aht20.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Temperature...: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    Serial.print(ahtValue);
    Serial.println(F(" +-0.3C"));
  }
  else
  {
    printStatus(); //print temperature command status

    if   (aht20.softReset() == true) Serial.println(F("reset success")); //as the last chance to make it alive
    else                             Serial.println(F("reset failed"));
  }

  delay(2000); //measurement with high frequency leads to heating of the sensor, see NOTE

  ahtValue = aht20.readHumidity(); //read another 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Humidity......: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    Serial.print(ahtValue);
    Serial.println(F(" +-2%"));
  }
  else
  {
    printStatus(); //print humidity command status
  }

  delay(2000); //measurement with high frequency leads to heating of the sensor, see NOTE

  /* DEMO - 2, temperature call will read 6-bytes via I2C, humidity will use same 6-bytes */
  Serial.println();
  Serial.println(F("DEMO 2: read 6-byte"));

  ahtValue = aht20.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Temperature: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    Serial.print(ahtValue);
    Serial.println(F(" +-0.3C"));
  }
  else
  {
    printStatus(); //print temperature command status
  }

  ahtValue = aht20.readHumidity(AHTXX_USE_READ_DATA); //use 6-bytes from temperature reading, takes zero milliseconds!!!

  Serial.print(F("Humidity...: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    Serial.print(ahtValue);
    Serial.println(F(" +-2%"));
  }
  else
  {
    printStatus(); //print temperature command status not humidity!!! RH measurement use same 6-bytes from T measurement
  }

  delay(10000); //recomended polling frequency 8sec..30sec
}


/**************************************************************************/
/*
    printStatus()

    Print last command status
*/
/**************************************************************************/
void printStatus()
{
  switch (aht20.getStatus())
  {
    case AHTXX_NO_ERROR:
      Serial.println(F("no error"));
      break;

    case AHTXX_BUSY_ERROR:
      Serial.println(F("sensor busy, increase polling time"));
      break;

    case AHTXX_ACK_ERROR:
      Serial.println(F("sensor didn't return ACK, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_DATA_ERROR:
      Serial.println(F("received data smaller than expected, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_CRC8_ERROR:
      Serial.println(F("computed CRC8 not match received CRC8, this feature supported only by AHT2x sensors"));
      break;

    default:
      Serial.println(F("unknown status"));    
      break;
  }
}

Semplicemente, la nano usa il classico ramo AVR standard e la libreria Wire implementa quel metodo, la libreria Wire che si trova nel "core" di Spencer Konde NON lo implementa e quindi non puoi usarlo.

Del resto ...

Portability Notes

This function was not available in the original version of the Wire library and might still not be available on all platforms. Code that needs to be portable across platforms and versions can use the WIRE_HAS_TIMEOUT macro, which is only defined when Wire.setWireTimeout(), Wire.getWireTimeoutFlag() and Wire.clearWireTimeout() are all available.

When this timeout feature was introduced on the AVR platform, it was initially kept disabled by default for compatibility, expecting it to become enabled at a later point. This means the default value of the timeout can vary between (versions of) platforms. The default timeout settings are available from the WIRE_DEFAULT_TIMEOUT and WIRE_DEFAULT_RESET_WITH_TIMEOUT macro.

Guglielmo

Io ho letto solo all'inizio del programma dove si evidenziavano i pin da usare, e c'era anche Attiny85.

Comunque nessun problema, uso la libreria

SparkFun_Qwiic_Humidity_AHT20.h

e non ho più questo problema.
Anche se non ha funzionato subito dall'inizio E SPIEGO PERCHE' (spero aiuti qualcun'altro).

Su arduino nano il programma di esempio della libreria Sparkfun funzionava egregiamente mentre su Attiny non ne voleva sapere. E non è bello ne facile cercare il perchè dato che non si può vedere il monitor seriale (si, lo so che c'è un modo per avere il serial monitor anche su Attiny).

Morale della favola, il programma funziona bene ANCHE SU ATTINY, solo che vanno messe due resistenze da 4k7 ohm sui due rami di I2C per metterli in pull-up (quindi collegate al +5volt).
Sul Nano il sensore AHT25 funzionava ugualmente anche senza resistenze (che comunque sono SEMPRE suggerite su ogni schema I2C).

Vabbé, succede. Fortuna che mi è venuto il dubbio leggendo il data sheet. :grinning_face_with_smiling_eyes:

... che non ha nulla a che vedere con il problema di compilazione del thread ... :roll_eyes:

Le pull-up sono SEMPRE obbligatorie con il bus I2C, su qualsiasi MCU ... alcune schede Arduino le hanno di base (es. Arduino MEGA), alcune breakout board anche (anzi, la maggior parte), ma comunque occorre SEMPRE verificare altrimenti ... una volta può andare un'altra no ... a secondo di quello che legge il pin digitale usato (... è la stessa cosa che lasciare flottante un pin in input).

Guglielmo

Ma infatti lo dico, anche se forse non era chiaro: il problema di compilazione lo avevo col programma relativo alla libreria AHTxx. Che ho abbandonato.
Per quel motivo ho ripiegato sulla libreria di Sparkfun, che invece mi dava problemi di funzionamento a causa delle due resistenze.

1 Like

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