Esp32 lora wifi v3.1

Hola. Tengo un problema con el modulo HELTEC ESP32 LoRa Wifi V3.1 :
Resulta que no hay manera de configurar las salidas PWM con la librería Heltec unofficial. Siempre sale error. No comprendo el porqué.
Me sale este error:
error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
41 | ledcAttachPin(ANALOG_PIN1, CHANNEL1);
El asunto va de recibir una cadena con los valores de dos analogicas e intentar sacarlas por dos GPIO en forma de pwm, ya que no cuenta con DAC.
He usado esa librería porque es la unica que me hace funcionar los módulos, tanto emisor como receptor.
Por si a alguien le ha pasado algo parecido, gracias y saludos.

¿Seleccionaste la placa correcta en la IDE?

segun yo el modulo heltec en el IDE de arduino es

TTGO LoRa32 OLED

Me pasó lo mismo, asi que te recomiendo que postees todo el código porque hay un problema en las lilbrerías o en el core utilizado.
En IDE me funcionaba y en VSC me daba error, y lo mismo si invertía lo que funciona en VSC pero no en IDE.

Esto funciona en IDE

Probablemente a esto se debía el problema (que a estas alturas supongo que ya solucionó)

Buenas tengo un problema con la placa Heltec Wifi Lora 32 (v3), tengo conectado un sensor de temperatura y humedad (AHT10). Trabajo con el programa Arduino IDE y ya tengo integrado el sensor con la placa, el problema está en que no soy capaz de mostrar algo en la pantalla y al mismo tiempo que mida el sensor y me dé los valores de temperatura y humedad. O falla uno, o falla el otro, es decir, o me muestra por pantalla (una palabra que yo ponga a modo de ejemplo) o recoge los valores de temperatura y humedad y los muestra por el monitor serie del programa.
Creo que hay conflicto en el bus de comunicación i2c pero no se como solucionarlo, ¿A alguien le ha pasado? ¿Como puedo solucinarlo? Gracias de antemano

AHT.cpp:

#include "AHT10.h"

//
/*
Constructor
*/
/
/
AHT10::AHT10(uint8_t address, ASAIR_I2C_SENSOR sensorName)
{
_address = address;
_sensorName = sensorName;
}

/**************************************************************************/
/*
begin()

Initialize I2C & configure the sensor, call this function before
doing anything else

NOTE:
- Wire.endTransmission() returned value:
  - 0 success
  - 1 data too long to fit in transmit data16
  - 2 received NACK on transmit of address
  - 3 received NACK on transmit of data
  - 4 other error

*/
/**************************************************************************/
#if defined(ESP8266)
bool AHT10::begin(uint8_t sda, uint8_t scl)
{
Wire.begin(sda, scl);
Wire.setClock(100000); //experimental! ESP8266 I2C bus speed: 50kHz..400kHz/50000..400000, default 100000
Wire.setClockStretchLimit(230); //experimental! default 230usec
#else
bool AHT10::begin(void)
{
Wire.begin();
Wire.setClock(100000); //experimental! AVR I2C bus speed: 31kHz..400kHz/31000..400000, default 100000
#endif

delay(AHT10_POWER_ON_DELAY); //wait for sensor to initialize

setNormalMode(); //one measurement+sleep mode

return enableFactoryCalCoeff(); //load factory calibration coeff
}

/**************************************************************************/
/*
readRawData()

Read raw measurment data from sensor over I2C

/
/**************************************************************************/
uint8_t AHT10::readRawData()
{
/
send measurment command */
Wire.beginTransmission(_address);
#if (ARDUINO) >= 100
Wire.write(AHT10_START_MEASURMENT_CMD); //send measurment command
Wire.write(AHT10_DATA_MEASURMENT_CMD); //send measurment parameter
Wire.write(AHT10_DATA_NOP); //send measurment parameter
#else
Wire.send(AHT10_START_MEASURMENT_CMD);
Wire.send(AHT10_DATA_MEASURMENT_CMD);
Wire.send(AHT10_DATA_NOP);
#endif
if (Wire.endTransmission(true) != 0) return AHT10_ERROR; //error handler, collision on I2C bus

if (getCalibrationBit() != 0x01) return AHT10_ERROR; //error handler, calibration coefficient turned off
if (getBusyBit(AHT10_USE_READ_DATA) != 0x00) delay(AHT10_MEASURMENT_DELAY); //measurement delay

/* read 6-bytes from sensor */
#if defined(VARIANT_ARDUINO_STM32)
Wire.requestFrom(_address, 6);
#else
Wire.requestFrom(_address, 6, true); //true - send stop after transmission & release I2C bus
#endif
if (Wire.available() != 6)
{
_rawDataBuffer[0] = AHT10_ERROR; //for condition when AHT10_USE_READ_DATA is used
return AHT10_ERROR; //check rxBuffer & error handler, collision on the i2c bus
}

/* read 6 bytes from "wire.h" rxBuffer */
#if (ARDUINO) >= 100
for (uint8_t i = 0; i < 6 ; i++)
{
_rawDataBuffer[i] = Wire.read();
}
#else
for (uint8_t i = 0; i < 6 ; i++)
{
_rawDataBuffer[i] = Wire.receive();
}
#endif

return true;
}

/**************************************************************************/
/*
readTemperature()

Read temperature, °C 

NOTE:
- temperature range      -40°C..+80°C
- temperature resolution 0.01°C
- temperature accuracy   ±0.3°C

*/
/**************************************************************************/
float AHT10::readTemperature(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA)
{
if (readRawData() == AHT10_ERROR) return AHT10_ERROR; //force to read data to _rawDataBuffer & error handler
}

if (_rawDataBuffer[0] == AHT10_ERROR) return AHT10_ERROR; //error handler, collision on I2C bus

uint32_t temperature = ((uint32_t)(_rawDataBuffer[3] & 0x0F) << 16) | ((uint16_t)_rawDataBuffer[4] << 8) | _rawDataBuffer[5]; //20-bit raw temperature data

return (float)temperature * 0.000191 - 50;
}

/**************************************************************************/
/*
readHumidity()

Read relative humidity, %

NOTE:
- prolonged exposure for 60 hours at humidity > 80% can lead to a
  temporary drift of the signal +3%. Sensor slowly returns to the
  calibrated state at normal operating conditions.
- relative humidity range      0%..100%
- relative humidity resolution 0.024%
- relative humidity accuracy   ±2%

*/
/**************************************************************************/
float AHT10::readHumidity(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA)
{
if (readRawData() == AHT10_ERROR) return AHT10_ERROR; //force to read data to _rawDataBuffer & error handler
}

if (_rawDataBuffer[0] == AHT10_ERROR) return AHT10_ERROR; //error handler, collision on I2C bus

uint32_t rawData = (((uint32_t)_rawDataBuffer[1] << 16) | ((uint16_t)_rawDataBuffer[2] << 8) | (_rawDataBuffer[3])) >> 4; //20-bit raw humidity data

float humidity = (float)rawData * 0.000095;

if (humidity < 0) return 0;
if (humidity > 100) return 100;
return humidity;
}

/**************************************************************************/
/*
softReset()

Restart sensor, without power off

NOTE:
- takes ~20ms
- all registers restores to default

*/
/**************************************************************************/
bool AHT10::softReset(void)
{
Wire.beginTransmission(_address);

#if (ARDUINO) >= 100
Wire.write(AHT10_SOFT_RESET_CMD);
#else
Wire.send(AHT10_SOFT_RESET_CMD);
#endif

if (Wire.endTransmission(true) != 0) return false; //safety check, make sure sensor reset

delay(AHT10_SOFT_RESET_DELAY);

setNormalMode(); //reinitialize sensor registers after reset

return enableFactoryCalCoeff(); //reinitialize sensor registers after reset
}

/**************************************************************************/
/*
setNormalMode()

Set normal measurment mode

NOTE:
- one measurement & power down??? no info in datasheet!!!

*/
/**************************************************************************/
bool AHT10::setNormalMode(void)
{
Wire.beginTransmission(_address);

#if (ARDUINO) >= 100
Wire.write(AHT10_NORMAL_CMD);
Wire.write(AHT10_DATA_NOP);
Wire.write(AHT10_DATA_NOP);
#else
Wire.send(AHT10_NORMAL_CMD);
Wire.send(AHT10_DATA_NOP);
Wire.send(AHT10_DATA_NOP);
#endif

if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete

delay(AHT10_CMD_DELAY);

return true;
}

/**************************************************************************/
/*
setCycleMode()

Set cycle measurment mode

NOTE:
- continuous measurement

*/
/**************************************************************************/
bool AHT10::setCycleMode(void)
{
Wire.beginTransmission(_address);

#if (ARDUINO) >= 100
if (_sensorName != AHT20_SENSOR) Wire.write(AHT10_INIT_CMD); //set command mode
else Wire.write(AHT20_INIT_CMD);
Wire.write(AHT10_INIT_CYCLE_MODE | AHT10_INIT_CAL_ENABLE); //0,[0,1],0,[1],0,0,0
Wire.write(AHT10_DATA_NOP);
#else
if (_sensorName != AHT20_SENSOR) Wire.send(AHT10_INIT_CMD);
else Wire.send(AHT20_INIT_CMD);
Wire.send(AHT10_INIT_CYCLE_MODE | AHT10_INIT_CAL_ENABLE);
Wire.send(AHT10_DATA_NOP);
#endif

if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete
return true;
}

/**************************************************************************/
/*
readStatusByte()

Read status byte from sensor over I2C

*/
/**************************************************************************/
uint8_t AHT10::readStatusByte()
{
#if defined(VARIANT_ARDUINO_STM32)
Wire.requestFrom(_address, 1);
#else
Wire.requestFrom(_address, 1, true); //true - send stop after transmission & release I2C bus
#endif
if (Wire.available() != 1) return AHT10_ERROR; //check rxBuffer & error handler, collision on I2C bus

/* read byte from "wire.h" rxBuffer */
#if (ARDUINO) >= 100
return Wire.read();
#else
return Wire.receive();
#endif
}

/**************************************************************************/
/*
getCalibrationBit()

Read Calibration bit from status byte

NOTE:
- 0, factory calibration coeff disabled
- 1, factory calibration coeff loaded

*/
/**************************************************************************/
uint8_t AHT10::getCalibrationBit(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA) _rawDataBuffer[0] = readStatusByte(); //force to read status byte

if (_rawDataBuffer[0] != AHT10_ERROR) return bitRead(_rawDataBuffer[0], 3); //get 3-rd bit
return AHT10_ERROR;
}

/**************************************************************************/
/*
enableFactoryCalCoeff()

Load factory calibration coefficients

/
/**************************************************************************/
bool AHT10::enableFactoryCalCoeff()
{
/
load factory calibration coeff */
Wire.beginTransmission(_address);

#if (ARDUINO) >= 100
if (_sensorName != AHT20_SENSOR) Wire.write(AHT10_INIT_CMD); //set command mode
else Wire.write(AHT20_INIT_CMD);
Wire.write(AHT10_INIT_CAL_ENABLE); //0,0,0,0,[1],0,0,0
Wire.write(AHT10_DATA_NOP); //0,0,0,0,0,0,0,0
#else
if (_sensorName != AHT20_SENSOR) Wire.send(AHT10_INIT_CMD);
else Wire.send(AHT20_INIT_CMD);
Wire.send(AHT10_INIT_CAL_ENABLE);
Wire.send(AHT10_DATA_NOP);
#endif

if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete

delay(AHT10_CMD_DELAY);

/*check calibration enable */
if (getCalibrationBit() == 0x01) return true;
return false;
}

/**************************************************************************/
/*
getBusyBit()

Read busy bit from status byte

NOTE:
- 0, sensor idle & sleeping
- 1, sensor busy & in measurement state

*/
/**************************************************************************/
uint8_t AHT10::getBusyBit(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA) _rawDataBuffer[0] = readStatusByte(); //force to read status byte

if (_rawDataBuffer[0] != AHT10_ERROR) return bitRead(_rawDataBuffer[0], 7); //get 7-th bit
return AHT10_ERROR;
}

AHT.h:

#ifndef AHT10_h
#define AHT10_h

#if defined(ARDUINO) && ((ARDUINO) >= 100) //arduino core v1.0 or later
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#if defined(AVR)
#include <avr/pgmspace.h> //for Arduino AVR PROGMEM support
#elif defined(ESP8266)
#include <pgmspace.h> //for Arduino ESP8266 PROGMEM support
#elif defined(VARIANT_ARDUINO_STM32)
#include <avr/pgmspace.h> //for Arduino STM32 PROGMEM support
#endif

#include <Wire.h>

#define AHT10_ADDRESS_0X38 0x38 //chip I2C address no.1 for AHT10/AHT15/AHT20, address pin connected to GND
#define AHT10_ADDRESS_0X39 0x39 //chip I2C address no.2 for AHT10 only, address pin connected to Vcc

#define AHT10_INIT_CMD 0xE1 //initialization command for AHT10/AHT15
#define AHT20_INIT_CMD 0xBE //initialization command for AHT20
#define AHT10_START_MEASURMENT_CMD 0xAC //start measurment command
#define AHT10_NORMAL_CMD 0xA8 //normal cycle mode command, no info in datasheet!!!
#define AHT10_SOFT_RESET_CMD 0xBA //soft reset command

#define AHT10_INIT_NORMAL_MODE 0x00 //enable normal mode
#define AHT10_INIT_CYCLE_MODE 0x20 //enable cycle mode
#define AHT10_INIT_CMD_MODE 0x40 //enable command mode
#define AHT10_INIT_CAL_ENABLE 0x08 //load factory calibration coeff

#define AHT10_DATA_MEASURMENT_CMD 0x33 //no info in datasheet!!! my guess it is DAC resolution, saw someone send 0x00 instead
#define AHT10_DATA_NOP 0x00 //no info in datasheet!!!

#define AHT10_MEASURMENT_DELAY 80 //at least 75 milliseconds
#define AHT10_POWER_ON_DELAY 40 //at least 20..40 milliseconds
#define AHT10_CMD_DELAY 350 //at least 300 milliseconds, no info in datasheet!!!
#define AHT10_SOFT_RESET_DELAY 20 //less than 20 milliseconds

#define AHT10_FORCE_READ_DATA true //force to read data
#define AHT10_USE_READ_DATA false //force to use data from previous read
#define AHT10_ERROR 0xFF //returns 255, if communication error is occurred

typedef enum : uint8_t
{
AHT10_SENSOR = 0x00,
AHT15_SENSOR = 0x01,
AHT20_SENSOR = 0x02
}
ASAIR_I2C_SENSOR;

class AHT10
{
public:

AHT10(uint8_t address = AHT10_ADDRESS_0X38, ASAIR_I2C_SENSOR = AHT10_SENSOR);

#if defined(ESP8266)
bool begin(uint8_t sda = SDA, uint8_t scl = SCL);
#else
bool begin();
#endif
uint8_t readRawData();
float readTemperature(bool readI2C = AHT10_FORCE_READ_DATA);
float readHumidity(bool readI2C = AHT10_FORCE_READ_DATA);
bool softReset();
bool setNormalMode();
bool setCycleMode();

private:
uint8_t _address;
ASAIR_I2C_SENSOR _sensorName;
uint8_t _rawDataBuffer[6] = {AHT10_ERROR, 0, 0, 0, 0, 0};

uint8_t readStatusByte();
uint8_t getCalibrationBit(bool readI2C = AHT10_FORCE_READ_DATA);
bool enableFactoryCalCoeff();
uint8_t getBusyBit(bool readI2C = AHT10_FORCE_READ_DATA);
};

#endif

Lee las Normas del Foro, abre tu propio tema (no secuestres temas ajenos) y adjunta el código como corresponde.

Moderador

Tema cerrado por secuestro del mismo.
Ya impartí instrucciones a @victorgusa