analogReadAveraging(4) causes Teensy 3.5 program to hang

Status
Not open for further replies.

paynterf

Well-known member
I have a very simple program to read the output from an Adafruit INA169 high-side current sensor and report the results to Serial1 (an HC-05 BT module):

Code:
void setup()
{
  Serial.begin(115200);
  delay(2000); //10/06/21 - just use fixed delay instead

  Serial1.begin(115200); //used HC-05 'AT' commands to set this speed
  while (!Serial1) {}

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ItotPin, INPUT); //I_total 1V/Amp
  //analogReadAveraging(4);

  MsecSinceLastLEDToggle = 0;

  Serial1.printf("Msec\tADVal\tTotVolts\tTotAmps\n");
}

void loop()
{
  if (Serial1.available())
  {
    CheckForUserInput();
  }

  if (MsecSinceLastLEDToggle >= 200)
  {
    MsecSinceLastLEDToggle -= 200;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

    //11/01/21 read I_tot value & print out as current
    int ItotVal = analogRead(ItotPin);
    double ItotVolts = ItotVal * VoltsPerCount;
    double ItotAmps = ItotVolts * AmpsPerVolt;
    Serial1.printf("%lu\t%d\t%2.2f\t%2.2f\n", millis(), ItotVal, ItotVolts, ItotAmps);

  }
}

If I uncomment the 'analogReadAveraging(4)' line, the program hangs. If I do nothing more than comment this line, the program runs fine, albeit with no averaging. In either case, the program compiles fine. What am I missing here?

TIA,

Frank
 
Hi Frank,

Are you sure this is the complete code? I get a compile error 'ItotPin' was not declared in this scope.

Edit: actually got a whole bunch of 'was not declared' errors.

Paul
 
Sorry - try this (added all defs, and commented out the call to CheckForUserInput()):

Code:
    Name:       T35_WallE3_V1.ino
    Created:	10/25/2021 2:37:04 PM
    Author:     FRANKNEWXPS15\Frank

    10/30/21 - Added TeensyOTADemo code for basic OTA updates
*/

/*
    Name:       TeensyOTADemo.ino
    Created:	10/9/2021 11:18:19 AM
    Author:     FRANKNEWXPS15\Frank

    This program demonstrates the use of 'board.txt' post-build instructions in
    conjunction with a small C# command-line program for seamless 'over-the-air' (OTA)
    firmware update for Teensy modules.

    Implementation of OTA update requires that Joe Pasquariello's 'FlasherX'
    code be added to the Teensy sketch as it is below, and some code to allow
    an external serial communications program to trigger the update process.

    In the demo sketch below, the 'FlasherX' additions are the '#include FlasherTxx.h'
    line and the addition of the FlasherX specific code at the bottom. The trigger
    mechanism is provided by the 'CheckForUserInput();' call in loop.  If the ASCII
    code for 'U' or 'u' is present on Serial1, the update process will be launched.

*/

#include "FlashTxx.h"		// TLC/T3x/T4x flash primitives
#include <elapsedMillis.h>

elapsedMillis MsecSinceLastLEDToggle; //used for LED blink timer
const double AREF = 3.3; //teensy default for analog inputs
const double AmpsPerVolt = 1.00; //default 10K Rs
const int MAX_AD_COUNT = 1023;
const double VoltsPerCount = AREF / MAX_AD_COUNT;
const int ItotPin = A18;

//Stream* FTDIport = &Serial1;	// Serial (USB) or Serial1, Serial2, etc. (UART)

#pragma region OTA UPDATE
//******************************************************************************
// hex_info_t	struct for hex record and hex file info
//******************************************************************************
typedef struct {	// 
  char* data;		// pointer to array allocated elsewhere
  unsigned int addr;	// address in intel hex record
  unsigned int code;	// intel hex record type (0=data, etc.)
  unsigned int num;	// number of data bytes in intel hex record

  uint32_t base;	// base address to be added to intel hex 16-bit addr
  uint32_t min;		// min address in hex file
  uint32_t max;		// max address in hex file

  int eof;		// set true on intel hex EOF (code = 1)
  int lines;		// number of hex records received  
} hex_info_t;

void read_ascii_line(Stream* serial, char* line, int maxbytes);
int  parse_hex_line(const char* theline, char* bytes,
  unsigned int* addr, unsigned int* num, unsigned int* code);
int  process_hex_record(hex_info_t* hex);
void update_firmware(Stream* serial, uint32_t buffer_addr, uint32_t buffer_size);

uint32_t buffer_addr, buffer_size; //09/20/21 copied from FlasherX - loop()
#pragma endregion OTA UPDATE

void setup()
{
  Serial.begin(115200);
  delay(2000); //10/06/21 - just use fixed delay instead

  Serial1.begin(115200); //used HC-05 'AT' commands to set this speed
  while (!Serial1) {}

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ItotPin, INPUT); //I_total 1V/Amp
  //analogReadAveraging(4);

  MsecSinceLastLEDToggle = 0;

  Serial1.printf("Msec\tADVal\tTotVolts\tTotAmps\n");
}

void loop()
{
  if (Serial1.available())
  {
    //CheckForUserInput();
  }

  if (MsecSinceLastLEDToggle >= 200)
  {
    MsecSinceLastLEDToggle -= 200;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

    //11/01/21 read I_tot value & print out as current
    int ItotVal = analogRead(ItotPin);
    double ItotVolts = ItotVal * VoltsPerCount;
    double ItotAmps = ItotVolts * AmpsPerVolt;
    Serial1.printf("%lu\t%d\t%2.2f\t%2.2f\n", millis(), ItotVal, ItotVolts, ItotAmps);

  }
}
 
Hi Frank, still complains about fatal error: FlashTxx.h: No such file or directory.
Anyway, don't have a T3.5 here so can't reproduce the issue you see on the same hardware.
What I would do is stripping the code to the bare minumum and see whether the 'hanging' is still there when analogReadAveraging(4); is uncommented.
Something like:
Code:
const int ItotPin = A18;

void setup(){
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ItotPin, INPUT);
  //analogReadAveraging(4);
}

void loop(){
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  int ItotVal = analogRead(ItotPin);
  Serial.println(ItotVal);
}

I assume that by 'the program hangs' you mean that the LED is no longer toggling or...?

Paul
 
Paul,

Oops - you can just comment out the #include "FlashTxx.h" line as those parts of the original program were commented out to make it as simple as possible.

Yes, by 'hang', I mean the LED no longer blinks.
 
I tried the code in #3 on a T3.6. It works (LED flashes) with the analogReadAveraging commented and uncommented.

Pete
 
While I'm on the subject - does analogReadAveraging(NUM_AVGS) apply to all analog pins?

TIA,

Frank
 
does analogReadAveraging(NUM_AVGS) apply to all analog pins?

Here's the function in cores\Teensy3\analog.c. It configures ADC0 and ADC1, so I think the answer is yes.

Code:
void analogReadAveraging(unsigned int num)
{

	if (calibrating) wait_for_cal();
	if (num <= 1) {
		num = 0;
		ADC0_SC3 = 0;
	} else if (num <= 4) {
		num = 4;
		ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
#ifdef HAS_KINETIS_ADC1
		ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
#endif
	} else if (num <= 8) {
		num = 8;
		ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
#ifdef HAS_KINETIS_ADC1
		ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
#endif
	} else if (num <= 16) {
		num = 16;
		ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
#ifdef HAS_KINETIS_ADC1
		ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
#endif
	} else {
		num = 32;
		ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
#ifdef HAS_KINETIS_ADC1
		ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
#endif
	}
	analog_num_average = num;
}
 
Thanks for clarifying this. Right now I'm using analog inputs for two different hardware functions, and since both should benefit from some averaging, I have used analogReadAverage(4).

Thanks for sharing the code. it is interesting to note that the only valid 'num' values are 0 (degenerate case), 4, 8, 16 & 32 - everything else gets converted to one of those values.

Frank
 
Thanks for sharing the code. it is interesting to note that the only valid 'num' values are 0 (degenerate case), 4, 8, 16 & 32

You know you have the code, right? It's in your TeensyDuino folder (Arduino\hardware\teensy\avr\cores\teensy3\analog.c). The ADC has 1 configuration bit to enable/disable hardware averaging, and 2 bits to control the amount of averaging when enabled (b00=4, b01=8, b10=16, b11=32).
 
Status
Not open for further replies.
Back
Top