ADC and ADC_battery doesnt work together

You can read the battery voltage with the function:

uint16_t voltage = getBatteryVoltage();

it worked fine.

You can read the voltage of the ADC-Pin with the function:

sensorValue = analogRead(ADC);

But when there is an analog signal, the battery voltage can no longer be read out, incorrect value is displayed.

When i open the connection to the ADC-Pin, the battery-voltage is shown right.

Here my test-Code:

void loop() {
// read the value from the sensor:
sensorValue = analogRead(ADC);

Serial.println (sensorValue);

batteryVoltage = getBatteryVoltage();

Serial.println (batteryVoltage);

delay(1000);
}

E_T

Hope this document make sense to you:
https://heltec-automation-docs.readthedocs.io/en/latest/cubecell/frequently_asked_questions.html#how-to-use-the-adc-pin-for-analogread-asr6501

In the new 6502 series, there have three ADC input channels.

1 Like

Thank you!

I will look for this device!

E_T

Is it possible to read an external analog signal on the CubeCell Capsule (HTCC-AC01), I don’t see an ADC signal on the pinout: https://github.com/HelTecAutomation/ASR650x-Arduino/blob/master/PinoutDiagram/HTCC-AC01.pdf?

According to the description of CubeCell Capsule Solar Sensor https://heltec.org/project/htcc-ac02/, this device is also based on the 6502, is there a ADC input available for measurements besides the battery?

1 Like

I’m also confused regarding the analog inputs. I’m using the plus board with three adc’s. I read that the maximum voltage on the analog inputs is 2.4 volts, so I added a voltage divider connected to the vext port and measured about 2.3 volts. If I now connect that power to e.g. adc2 the values of adc1 and 3 also go up and are almost equal to adc2. What am I doing wrong here?

Good Day - I have been doing some validation testing on the CubeCell AB02S board and see that the ADC2 and ADC3 channels are ‘interacting’. For example having the turned on the VBAT_ADC_CTL (it’s LOW for ‘ON’) and reading the ADC1 I get a sensible number (Yes I know this is halved by the resistor divider). But if I inject a separate voltage into either ADC2 or ADC2 this will then affect the VBAT result.

In fact they all interact with one another, if I inject 1.0V into ADC3 then all of the other ADC results will report around 1000 (mV).

Have a lot of experience with the CY8… family of PSoC Ics, I suspect the internal MUX selection is not programmed properly on the ASR6502 (I have made this error before on those PSoC projects!)

If I am correct with this it would mean we would need a file to flash into the 6502 to correct this error OR (Hopefully) there is another instruction I am missing that needs to be included between the ADC reads?

Here is the code snippet:

digitalWrite(VBAT_ADC_CTL,LOW); // enable battery (1/2) onto ADC1
delay(500);

voltage=analogRead(ADC1);//return the voltage in mV, max value can be read is 2400mV
Serial.print("ADC1 (Batt) = ");
Serial.println((voltage));
delay(5000);
digitalWrite(VBAT_ADC_CTL,HIGH); // disable battery from ADC1

pixels.setPixelColor(0, pixels.Color(0, i, 0)); // Green
pixels.show(); // Send the updated pixel colors to the hardware.

voltage=analogRead(ADC2);//return the voltage in mV, max value can be read is 2400mV
Serial.print("ADC2 = ");
Serial.println(voltage);
delay(5000);

pixels.setPixelColor(0, pixels.Color(0, 0, i)); // Blu?
pixels.show(); // Send the updated pixel colors to the hardware.

voltage=analogRead(ADC3);//return the voltage in mV, max value can be read is 2400mV
Serial.print(“ADC3 = “);
Serial.println(voltage);
Serial.println(””);
delay(5000);

1 Like

@npaterson Thanks for the hint. I just tried flashing the firmware 3.1.1, but the adc’s are still all reacting to each other. If I apply a voltage to adc2 all adc’s go up and if I also attach a ground to adc3 all adc’s go down. Something is wrong here.

@Supporter Could you please take a look at this? Is this an error in the firmware?

This could be only a problem when there is an open connector.

Try to put different Voltage on the two ADC Inputs and then look at the result.

I’ve just tried that. I attached 1 volt to adc3 and 2 volts to acd2 and I get 1 volt on both adc’s. If I also pull adc1 to ground I get only about 500 mv on all pins. Any idea what could cause this problem?

Ok, that’s not good news. I hope then, it is only a bad implementation of arduino-ADC

Hi Ernst - I know exactly where the fault lines (in the PSOC Mux implementation), I was hoping that there might be an ‘Arduino’ level command to actually switch the onboard mux but as I am a very long time ‘c’ guy and only new to C++ I needed to ask.

If I could get my hands on the PSOC source I know I can fix this and as the SWD-Data and SWD-Clk are pinned out to the header we would have a good chance of sorting this out.

I have sent a seperate query to Support in the meantime I’ll avoid using ADC2 or ADC3

I guess the firmware is not open source. At least I didn’t find anything on GitHub. I hope that HellTec will take a look at this.

@npaterson Did you receive an answer from the support in the meantime? Or is there someone else we could ask here in the forum to take a look at this?

There’s a commit on GitHub “fixed an adc bug” in the compiled library from about 6 days ago. It would be worth updating your library (from GitHub) and repeating your tests.

@bwooce Thanks for the hint. I’m using Platform.io to develop and I guess there the library there was not updated yet. I’ve now replaced the files manually with the one’s from the master repository and now the ADC’s are working. :grinning: Thanks again for the hint!

2 Likes

This seems to be working on the July bug fix CubeCellLib.a , but I checked with the latest commit the problem is still there. Battery reading seems correct 1st but ADC is half, then battery reading drops to 0. Please check. Thank you.

hi,

what is your board’s type? could you post your code?

Hi, below is my code,

#include “LoRaWan_APP.h”
#include “Arduino.h”
#include “Wire.h”

#define VEXT_CONTROL 1
#define DEBUG_LOGS_ENABLED 1
//LED INDICATOR
#ifndef LoraWan_RGB
#define LoraWan_RGB 0
#endif

//LOW POWER CYCLE
#define timetosleep 150 //before sleep
#define timetowake 850 //before waking
typedef enum
{
ReadVoltage,
TX,
TXBattery
}States_t;

States_t state;
static TimerEvent_t sleep;
static TimerEvent_t wakeUp;
uint8_t lowpower=0;
void onSleep(void);
void onWakeup(void);

long lastSent=0;
float sensorValue = 0.0f;
float oldSensorValue = 0.0f;
uint16_t battery = 0;
bool isTimeoutLastSent = false;

void setup() {

delay(1000);
Serial.begin(9600);
delay(1000);
boardInitMcu( );
sensorValue = 0.0f;
oldSensorValue = 0.0f;
LoraInit();
state=TX; 

TimerInit( &sleep, onSleep );
TimerInit( &wakeUp, onWakeUp );
PowerDownExternalPeripherals();
onWakeUp();

}

//CUBECELL SPECIFIC SLEEP TIMING MECHANISM
void onSleep()
{
if(DEBUG_LOGS_ENABLED)Serial.println(“low power:”);

lowpower=1;
TimerSetValue( &wakeUp, timetowake );
TimerStart( &wakeUp );
}
void onWakeUp()
{
if(DEBUG_LOGS_ENABLED) Serial.println(“wakeup:”);
lowpower=0;
TimerSetValue( &sleep, timetosleep );
TimerStart( &sleep );
}

bool LoraIRQProcess()
{
//LoRa.IRQProcess;
//and some check if last message exceeded the timeout
return false;
}
void loop()
{

if(lowpower)
{
battery = GetBattery(); //added this

//if(DEBUG_LOGS_ENABLED){ Serial.println("Sleeping");}
DeepSleepDevice(); 

}
else
{
switch(state)
{
case TX:
{
//update the old value if it is to be sent, so that it will not consider gradual increase,
//otherwise it not sent at all if the increase in speed is very slow
oldSensorValue = sensorValue;
lastSent = millis();
state = ReadVoltage; //default state if it is not on sleep
Send();
break;
}
case TXBattery:
{
lastSent = millis();
state = ReadVoltage; //default state if it is not on sleep
SendBattery();
break;
}
case ReadVoltage:
{
//Serial.println(millis());
long tDurSinceLast = millis()-lastSent;
if(tDurSinceLast < 100)
break;
if((millis()/1000)%30 == 0) //every 60 seconds send battery reading
{
state = TXBattery;
}
else if((millis()/1000)%10 == 0)
//every 30 seconds mandatory send reading, NOTE:millis() resets after 50 days
{
Serial.println(“Sending because of 10 sec”);
turnOnRGB(COLOR_SEND,0); //blink to know that it is still active
sensorValue = analogRead(ADC2);
state = TX;
}
else if(isTimeoutLastSent) //send if time out
{
Serial.println(“Sending because of timeout”);
sensorValue = analogRead(ADC2);
state = TX;
}
else
{

          sensorValue = analogRead(ADC2);
          
          float changeValue = ((sensorValue - oldSensorValue));
          float percentChange = oldSensorValue < sensorValue ? (abs(changeValue)/(sensorValue)) : (abs(changeValue)/(oldSensorValue));
          if(percentChange > 0.10) //if greater than 10 percent change, send the value
          {
              Serial.println("Sending because of change");
              state = TX;
          }
          else if(tDurSinceLast > 100)//lora timeout  
            //if lora_tx_timeout is already done, then sleep(means longer than that there is nothing to do but read sensor)
          {
             lowpower = 1;
          }

          //if none of the conditions are met, state = ReadVoltage
        }
        break;
    }
    default:
      break;
  }

}
isTimeoutLastSent = LoraIRQProcess(); //just simply returns if the last message was not sent

}
uint16_t GetBattery(){
pinMode(VBAT_ADC_CTL, OUTPUT);
digitalWrite(VBAT_ADC_CTL, LOW);
uint16_t voltage = getBatteryVoltage();
digitalWrite(VBAT_ADC_CTL, HIGH);
return voltage;
}
void PowerDownExternalPeripherals()
{

    Wire.end();
    pinMode(GPIO5,ANALOG);
    pinMode(GPIO6,ANALOG);
    pinMode(GPIO7,ANALOG);
    pinMode(ADC,INPUT);
    VextOff();

}
void DeepSleepDevice()
{
//Lora.Sleep(); //can also be down after sending packet
turnOffRGB();
PowerDownExternalPeripherals();
lowPowerHandler();
}

void VextOn()
{
    #if defined(VEXT_CONTROL)
        pinMode(Vext,OUTPUT);
        digitalWrite(Vext, HIGH);  //usually high means off but need to check per mcu
    #endif
}
void VextOff()
{
    #if defined(VEXT_CONTROL)
        pinMode(Vext,OUTPUT);
        digitalWrite(Vext, LOW);  //usually high means off but need to check per mcu
    #endif
}

void LoraInit()
{
//lora initialization
}

void Send()
{
//using lora
}
void SendBattery()
{
//using lora

}