Having a problem where calling analogRead(A7) causes my code to go off the rails when attempting to read VBAT. Code worked fine on a 32u4 LoRa Feather.
Hardware:
Feather M0 LoRa
OLED FeatherWing
AdaLogger FeatherWing
...all mounted on a tripler board
Sofware:
Arduino IDE 1.83 on Windows 7
Arduino SAMD Board 1.6.15
Adafruit SAMD Boards 1.0.19
My suspicion is that the buttons (A,B,C, especially A on D9) on the OLED FeatherWing are creating a conflict with A7. As a test, I compiled and ran the code without any problems using A0 through A5 in place of A7 in analogRead(...).
Pressing the A button on the OLED FeatherWing causes the orange/yellow LED to pulse, but I have no code which controls that LED (it looks hard to do!).
I did read this year old post that seemed to solve the problem but, wonder if there was a regression defect sometime in the last year viewtopic.php?f=57&t=100823&p=505083&hi ... ex#p505083. Doesn't seem like a good idea to roll everything back to year old stuff.
Or maybe something else is in play.
Thanks,
Cliff
FeatherM0 analogRead(A7) problem
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
Does it work OK by itself? Not in the tripler or attched to any of the wings. Also, describe 'off the rails' in more detail.
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
Yes, it works fine when the Feather M0 w/LoRa is standalone - meaning the VBAT code snippet in the product tutorial works fine.
By "off the rails", the program does not function as expected when the buttons on the OLED display are pressed. It behaves as if program memory has been overwritten. Over time, the program simply crashes. The buttons increment/decrement a two dimensional int array which controls what is displayed on the OLED FeatherWing. If analongRead(A7) is replaced with A0, A1, A2, A3, A4, or A5, then everything works fine.
For the OLED FeatherWing, the buttons are defined as:
...and then the pinModes are set:
I think the issue is with BUTTON_A and VBATPIN.
By "off the rails", the program does not function as expected when the buttons on the OLED display are pressed. It behaves as if program memory has been overwritten. Over time, the program simply crashes. The buttons increment/decrement a two dimensional int array which controls what is displayed on the OLED FeatherWing. If analongRead(A7) is replaced with A0, A1, A2, A3, A4, or A5, then everything works fine.
For the OLED FeatherWing, the buttons are defined as:
Code: Select all
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
Code: Select all
pinMode(BUTTON_A, INPUT_PULLUP);
pinMode(BUTTON_B, INPUT_PULLUP);
pinMode(BUTTON_C, INPUT_PULLUP);
pinMode(VBATPIN, INPUT);
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
...forgot to add, the pin is being told to be both an analog input (no pull up) and digital input (with pull up).
https://learn.adafruit.com/adafruit-fea ... nd-pullups
https://learn.adafruit.com/adafruit-fea ... nd-pullups
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
Hmmm. Yeah. So something with the setup. Post a photo of your setup and complete code that demonstrates the issue.
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
Here is the code. It is quite peppered with various commented out sections that were a result of debugging activities.
Code: Select all
// LoRaNodeV1M0
#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
// Required for Serial on Zero based boards
#define Serial SERIAL_PORT_USBVIRTUAL
#endif
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SD.h>
#define USE_SERIAL_DEBUG
#define USE_SD
#undef USE_LORA
// LoRa Node
//
// This is the code that the sensors are wired to and connects via LoRa to the master unit
const char* NetworkID = "A";
const char* NodeID = "1";
const int BroadcastSecs = 5;
int thepin = A5;
#ifdef USE_LORA
#include <RH_RF95.h>
#endif
//LoRa for feather m0
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 3
#define VBATPIN A7
Adafruit_SSD1306 display = Adafruit_SSD1306();
#if defined(ESP8266)
#define BUTTON_A 0
#define BUTTON_B 16
#define BUTTON_C 2
#define LED 0
#elif defined(ESP32)
#define BUTTON_A 15
#define BUTTON_B 32
#define BUTTON_C 14
#define LED 13
#elif defined(ARDUINO_STM32F2_FEATHER)
#define BUTTON_A PA15
#define BUTTON_B PC7
#define BUTTON_C PC5
#define LED PB5
#elif defined(TEENSYDUINO)
#define BUTTON_A 4
#define BUTTON_B 3
#define BUTTON_C 8
#define LED 13
#elif defined(ARDUINO_FEATHER52)
#define BUTTON_A 31
#define BUTTON_B 30
#define BUTTON_C 27
#define LED 17
#else // 32u4, M0, and 328p
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
#define LED 13
#endif
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
#ifdef USE_LORA
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
#endif
RTC_PCF8523 rtc;
DateTime now;
#ifdef USE_SD
// SD card
const int chipSelect = 10; // for SD card on Feather
File LogFile;
#endif // USE_SD
int TXCount = 0;
char tmp[256];
char tmp32[32];
char tmp16[16];
char tmp8[8];
//char RXBuffer[256];
char TXBuffer[256];
char DateTimeString[64];
char VersionDate[16];
char VersionTime[16];
// display page control
int ButtonCount[3][2];
struct SensorsStruct
{
char Name[16];
char Value[16];
char UOM[16];
char ChannelID[4];
bool Upoad;
} Sensors[16];
int SensorCount = 0;
int SensorTotalCount = 0;
int LastSeconds = -1000;
int ThisSeconds = 0;
char WhirlyGigCharacter;
char Parameter[64];
void setup()
{
delay(500);
// configure the buttons on the display
ButtonCount[0][0] = 1; // default page = 1
ButtonCount[0][1] = 2; // number of pages
ButtonCount[1][0] = 0; // not default page
ButtonCount[1][1] = 4; // number of pages
ButtonCount[2][0] = 0; // not default page
ButtonCount[2][1] = 0; // number of pages - this will be overwritten by Sensors() based on number of sensors
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
display.clearWriteError();
display.setTextSize(2); // this is a multiplier: 1, 2, 3 and 4 are normal values
display.setTextColor(WHITE);
strcpy(Parameter, "Firmware\nReleased...");
DisplayMessage(Parameter);
delay(1500);
// month part
strncpy(tmp32, __DATE__, 3);
tmp32[3] = '\0';
if (strcmp("Jan", tmp32) == 0)
strcpy(tmp8, "01");
else if (strcmp("Feb", tmp32) == 0)
strcpy(tmp8, "02");
else if (strcmp("Mar", tmp32) == 0)
strcpy(tmp8, "03");
else if (strcmp("Apr", tmp32) == 0)
strcpy(tmp8, "04");
else if (strcmp("May", tmp32) == 0)
strcpy(tmp8, "05");
else if (strcmp("Jun", tmp32) == 0)
strcpy(tmp8, "06");
else if (strcmp("Jul", tmp32) == 0)
strcpy(tmp8, "07");
else if (strcmp("Aug", tmp32) == 0)
strcpy(tmp8, "08");
else if (strcmp("Sep", tmp32) == 0)
strcpy(tmp8, "09");
else if (strcmp("Oct", tmp32) == 0)
strcpy(tmp8, "10");
else if (strcmp("Nov", tmp32) == 0)
strcpy(tmp8, "11");
else if (strcmp("Dec", tmp32) == 0)
strcpy(tmp8, "12");
// year part
strcpy(tmp32, __DATE__);
strncpy(tmp16, &tmp32[7], 4);
tmp16[4] = '\0';
// day part
strncpy(tmp, &tmp32[4], 2);
if (tmp[0] == ' ')
tmp[0] = '0';
tmp[2] = '\0';
strcpy(tmp32, tmp);
sprintf(tmp, "%s-%s-%s\n%s P", tmp16, tmp8, tmp32, __TIME__);
sprintf(VersionDate, "%s-%s-%s", tmp16, tmp8, tmp32);
sprintf(VersionTime, "%s P", __TIME__);
DisplayMessage(tmp);
delay(1500);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUTTON_A, INPUT_PULLUP);
pinMode(BUTTON_B, INPUT_PULLUP);
pinMode(BUTTON_C, INPUT_PULLUP);
pinMode(VBATPIN, INPUT);
pinMode(A2, INPUT);
pinMode(10, OUTPUT);
delay(2000);
#ifdef USE_SD
strcpy(Parameter, "Init\nSD Card...");
DisplayMessage(Parameter);
if (!SD.begin(chipSelect))
{
strcpy(Parameter, "SD Card\nFailed!");
DisplayMessage(Parameter);
delay(7000);
return;
}
#endif
delay(2000);
#ifdef USE_SERIAL_DEBUG
strcpy(Parameter, "Init\nSerial...");
DisplayMessage(Parameter);
Serial.begin(9600);
delay(100);
#endif
#ifdef USE_LORA
strcpy(Parameter, "Init\BANNED...");
DisplayMessage(Parameter);
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
while (!rf95.init())
{
strcpy(Parameter, "Init\BANNED Failed!");
DisplayMessage(Parameter);
while (1);
}
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ))
{
strcpy(Parameter, "Set Freq Failed!");
DisplayMessage(Parameter);
while (1);
}
delay(2000);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
rf95.setTxPower(23, false);
#endif
if (!rtc.begin())
{
strcpy(Parameter, "RTC Failed!");
DisplayMessage(Parameter);
while (1);
}
delay(100);
if (!rtc.initialized())
{
strcpy(Parameter, "Init\nClock...");
DisplayMessage(Parameter);
// Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
rtc.adjust(DateTime(2000, 1, 1, 00, 00, 0));
}
// use this to initialize the clock one time
// this is local time not the preferred UTC time, but good enough for testing
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
WhirlyGig(true);
strcpy(Parameter, "Ready");
DisplayMessage(Parameter);
delay(1500);
}
void loop()
{
now = rtc.now();
sprintf(DateTimeString, "%4d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
WhirlyGigCharacter = WhirlyGig(false);
SensorsRead();
delay(50);
// Home Button
if (!digitalRead(BUTTON_A))
{
if (KeyPress(BUTTON_A, false))
{
ButtonCount[0][0] = ((ButtonCount[0][0]++) % ButtonCount[0][1]) + 1;
ButtonCount[1][0] = 0;
ButtonCount[2][0] = 0;
//Serial.println(ButtonCount[0][0], DEC);
}
}
// Configuration Button
if (!digitalRead(BUTTON_B))
{
if (KeyPress(BUTTON_B, false))
{
ButtonCount[0][0] = 0;
ButtonCount[1][0] = ((ButtonCount[1][0]++) % ButtonCount[1][1]) + 1;
ButtonCount[2][0] = 0;
//Serial.println(ButtonCount[1][0], DEC);
}
}
// Sensors Button
if (!digitalRead(BUTTON_C))
{
if (KeyPress(BUTTON_C, false))
{
ButtonCount[2][0] = ((ButtonCount[2][0]++) % SensorTotalCount) + 1;
ButtonCount[0][0] = 0;
ButtonCount[1][0] = 0;
//Serial.println(ButtonCount[2][0], DEC);
}
}
//*********************************************
// set active display based on button settings
//*********************************************
display.clearDisplay();
display.setCursor(0, 0);
// Home Button
// 1 = VaporSafe/Date
if (ButtonCount[0][0] == 1)
{
strcpy(tmp32, &DateTimeString[11]);
sprintf(tmp, "%cVaporSafe\n%s Z", WhirlyGigCharacter, tmp32);
if (now.second() % 2 == 0)
ButtonCount[0][0] = 2;
}
// Home Button
// 1 = VaporSafe/Time
else if (ButtonCount[0][0] == 2)
{
strncpy(tmp32, DateTimeString, 10);
tmp32[10] = '\0';
sprintf(tmp, "%cVaporSafe\n%s", WhirlyGigCharacter, tmp32);
if (now.second() % 2 == 1)
ButtonCount[0][0] = 1;
}
// Configuration Button
// 1 = Date/Time
// 2 = Network/Node
// 3 = Firmware Version Date
// 4 = Firmware Version Time
else if (ButtonCount[1][0] == 1)
{
DateTimeString[10] = '\n';
DateTimeString[19] = ' ';
DateTimeString[20] = 'Z';
DateTimeString[21] = '\0';
strcpy(tmp, DateTimeString);
}
else if (ButtonCount[1][0] == 2)
{
strcpy(tmp, "Network:A\nNode:1");
}
else if (ButtonCount[1][0] == 3)
{
strcpy(tmp, "Ver Date:\n");
strcat(tmp, VersionDate);
}
else if (ButtonCount[1][0] == 4)
{
strcpy(tmp, "Ver Time:\n");
strcat(tmp, VersionTime);
}
// Sensor button
// scroll through all of the Sensors[]
else if (ButtonCount[2][0] > 0)
{
sprintf(tmp, "%c %s\n%s %s", WhirlyGigCharacter, Sensors[ButtonCount[2][0] - 1].Name, Sensors[ButtonCount[2][0] - 1].Value, Sensors[ButtonCount[2][0] - 1].UOM);
}
else
{
sprintf(tmp, "%cButtons\n%d%d %d%d %d%d", WhirlyGigCharacter, ButtonCount[0][0], ButtonCount[0][1], ButtonCount[1][0], ButtonCount[1][1], ButtonCount[2][0], ButtonCount[2][1]);
}
//sprintf(tmp, "%cButtons\n%d%d %d%d %d%d", WhirlyGigCharacter, ButtonCount[0][0], ButtonCount[0][1], ButtonCount[1][0], ButtonCount[1][1], ButtonCount[2][0], ButtonCount[2][1]);
display.print(tmp);
display.display();
ThisSeconds = now.second();
// check to see if we should send the data
if (abs(LastSeconds - ThisSeconds) >= BroadcastSecs)
{
TXCount++;
strcpy(TXBuffer, DateTimeString);
//sprintf(TXBuffer, "*%s|%s|%d|114|%s|%s", NetworkID, NodeID, TXCount, DateTimeString);
//for (int i = 0; i < SensorTotalCount; i++)
//{
// if (Sensors[i].Upoad)
// {
// strcat(TXBuffer, "|");
// strcat(TXBuffer, Sensors[i].ChannelID);
// strcat(TXBuffer, "|");
// strcat(TXBuffer, Sensors[i].Value);
// strcat(TXBuffer, "\n");
// }
//}
// Debug(TXBuffer);
//LogData(TXBuffer);
// tx(TXBuffer);
LastSeconds = ThisSeconds;
}
}
#ifdef USE_LORA
bool tx(char *Packet)
{
bool Success = false;
digitalWrite(LED_BUILTIN, HIGH);
// Serial.println("Sending to rf95_server");
// Send a message to rf95_server
//char radiopacket[20] = "Hello World # ";
// Serial.print("Sending "); Serial.println(radiopacket);
//radiopacket[19] = 0;
//Serial.println("Sending..."); delay(10);
rf95.send((uint8_t *)Packet, strlen(Packet));
//Serial.println("Waiting for packet to complete..."); delay(10);
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
//Serial.println("Waiting for reply...");
delay(10);
if (rf95.waitAvailableTimeout(1100))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Success = true;
//Debug("Got reply: ");
//Debug((char*)buf);
//Debug("RSSI: ");
//Serial.println(rf95.lastRssi(), DEC);
}
else
{
//Debug("Receive failed");
}
}
else
{
//Debug("No reply, is there a listener around?");
}
delay(1);
digitalWrite(LED_BUILTIN, LOW);
return(Success);
}
#endif
/*
void rx()
{
if (rf95.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.recv(buf, &len))
{
digitalWrite(LED, HIGH);
RH_RF95::printBuffer("Received: ", buf, len);
strncpy(RXBuffer, (char*)buf, len);
RXBuffer[len] = '\0';
Serial.print("Got: ");
Serial.println(RXBuffer);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
delay(10);
digitalWrite(LED, LOW);
RXCount++;
}
else
{
//Serial.println("Receive failed");
}
}
}
*/
char WhirlyGig(bool Init)
{
static byte Position;
if (Init)
Position = -1;
Position++;
if (Position == 0)
return(124); // |
if (Position == 1)
return(47); // /
if (Position == 2)
return(45); // -
if (Position == 3)
return(92); // backslash
if (Position == 4)
return(124); // |
if (Position == 5)
return(47); //
if (Position == 6)
return(45); // -
if (Position == 7)
{
Position = -1;
return(92); // backslash
}
return('*'); // indicates an error
}
void Debug(char *s)
{
#ifdef USE_SERIAL_DEBUG
Serial.println(s);
#endif
}
void DisplayMessage(char *Message)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print(Message);
display.display();
}
void LogData(char *data)
{
#ifdef USE_SD
LogFile = SD.open("q.txt", FILE_WRITE);
if (LogFile)
{
LogFile.println(data);
LogFile.close();
}
else
{
strcpy(Parameter, "SD Card Problem");
DisplayMessage(Parameter);
delay(5000);
}
#endif
}
float SensorBatteryVoltage(int Pin)
{
float ADResolution = 1024.0;
float measuredvbat = 0;
if (Pin != A7)
measuredvbat = analogRead(A7);
measuredvbat = measuredvbat * 6.6;
measuredvbat /= ADResolution; // convert to voltage
return(measuredvbat);
}
float SensorDiffPressure(int pin)
{
float ADResolution = 4096.0;
float measuredvbat = analogRead(thepin);
measuredvbat = measuredvbat * 6.6;
measuredvbat /= ADResolution; // convert to voltage
return(measuredvbat);
}
bool KeyPress(int Pin, bool PressedState)
{
unsigned long Startms = millis();
unsigned long Diffms = millis() - Startms;
bool CurrentState = PressedState;
do
{
CurrentState = digitalRead(Pin);
Diffms = millis() - Startms;
} while ((Diffms < 10) && (CurrentState == PressedState));
return(CurrentState == PressedState);
}
void SensorsRead()
{
int i = 0;
int ADValue = 0;
ADValue = analogRead(thepin);
strcpy(Sensors[i].Name, "Uptime");
strcpy(Sensors[i].UOM, "Secs");
sprintf(tmp, "%lu", millis() / 1000);
strcpy(Sensors[i].Value, tmp);
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = true;
i++;
strcpy(Sensors[i].Name, "Bat Volt");
strcpy(Sensors[i].UOM, "VDC");
dtostrf(SensorBatteryVoltage(), 3, 2, tmp);
strcpy(Sensors[i].Value, tmp);
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = true;
i++;
strcpy(Sensors[i].Name, "Bat Volt");
strcpy(Sensors[i].UOM, "A/D");
sprintf(tmp, "%d", 1);
strcpy(Sensors[i].Value, tmp);
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = true;
i++;
strcpy(Sensors[i].Name, "DiffPrss");
strcpy(Sensors[i].UOM, "Pa");
dtostrf(SensorDiffPressure(ADValue), 3, 1, tmp);
strcpy(Sensors[i].Value, tmp);
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = true;
i++;
strcpy(Sensors[i].Name, "DiffPrss");
strcpy(Sensors[i].UOM, "A/D");
sprintf(tmp, "%d", ADValue);
strcpy(Sensors[i].Value, tmp);
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = false;
i++;
strcpy(Sensors[i].Name, "End Of\nSensors");
strcpy(Sensors[i].UOM, "");
strcpy(Sensors[i].Value, "");
strcpy(Sensors[i].ChannelID, "0");
Sensors[i].Upoad = false;
i++;
SensorTotalCount = i;
}
char *dtostrf(double value, int width, unsigned int precision, char *result)
{
int decpt, sign, reqd, pad;
const char *s, *e;
char *p;
s = fcvt(value, precision, &decpt, &sign);
if (precision == 0 && decpt == 0) {
s = (*s < '5') ? "0" : "1";
reqd = 1;
}
else {
reqd = strlen(s);
if (reqd > decpt) reqd++;
if (decpt == 0) reqd++;
}
if (sign) reqd++;
p = result;
e = p + reqd;
pad = width - reqd;
if (pad > 0) {
e += pad;
while (pad-- > 0) *p++ = ' ';
}
if (sign) *p++ = '-';
if (decpt <= 0 && precision > 0) {
*p++ = '0';
*p++ = '.';
e++;
while (decpt < 0) {
decpt++;
*p++ = '0';
}
}
while (p < e) {
*p++ = *s++;
if (p == e) break;
if (--decpt == 0) *p++ = '.';
}
if (width < 0) {
pad = (reqd + width) * -1;
while (pad-- > 0) *p++ = ' ';
}
*p = 0;
return result;
}
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
You will want to modify this function, which has a temporary workaround:
Code: Select all
float SensorBatteryVoltage(int Pin)
{
float ADResolution = 1024.0;
float measuredvbat = 0;
if (Pin != A7)
measuredvbat = analogRead(A7);
measuredvbat = measuredvbat * 6.6;
measuredvbat /= ADResolution; // convert to voltage
return(measuredvbat);
}
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
Here is the pic - pretty basic, however I did add a 100uF capacitor between VCC and ground in order to address an issue with the RTC FeatherWing. You can't see it because it is underneath the component side of the board.
viewtopic.php?f=57&t=98219&p=599241&hil ... me#p599241
viewtopic.php?f=57&t=98219&p=599241&hil ... me#p599241
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
Looks like battery sense and digital input 9 are tied together. And button A of the OLED Feather Wing is attached to digital 9. So they are going to interfere. But I'm seeing the same conflict on the 32u4 board as well. How did you get it to work there?
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
It works on the 32u4 because VBATPIN is on A9, not A7 as in the M0 since it has fewer A/Ds. Seems like the solution is to move VBATPIN on the M0 somewhere else (A0-A5).
https://learn.adafruit.com/adafruit-fea ... ng-battery
https://learn.adafruit.com/adafruit-fea ... ng-battery
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
True. But they are both physically connected to the same ~9 pin on the Feather header, which is where button A from the OLED will come in. So I'd expect the interference to be there on both.
Or to put it another way, the voltage divider is physically connected to ~9, so whatever is attached there is going to interfere with battery sense.
Or to put it another way, the voltage divider is physically connected to ~9, so whatever is attached there is going to interfere with battery sense.
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
Ah yes, your'e right!
I think that is why I was heading down the SAMD path with this. I've been struggling with it all weekend since I received the M0 boards on Friday.
Perhaps it is something specific about the M0 internals. Maybe related to the inputs and pullup changes from the 32u4?
I think that is why I was heading down the SAMD path with this. I've been struggling with it all weekend since I received the M0 boards on Friday.
Perhaps it is something specific about the M0 internals. Maybe related to the inputs and pullup changes from the 32u4?
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
They're very different chips, but still, either should have an issue. Pressing the button on the OLED will short the input to ground which will throw off the reading. Although either should work as long as the button is not pressed.Maybe related to the inputs and pullup changes from the 32u4?
I guess you can either sense the battery or read BUTTON A, but not both. At least not at the same time. So by doing this:
Code: Select all
pinMode(BUTTON_A, INPUT_PULLUP);
pinMode(BUTTON_B, INPUT_PULLUP);
pinMode(BUTTON_C, INPUT_PULLUP);
pinMode(VBATPIN, INPUT);
What/where was this LED?Pressing the A button on the OLED FeatherWing causes the orange/yellow LED to pulse, but I have no code which controls that LED
- k3ll
- Posts: 11
- Joined: Mon Nov 26, 2012 12:18 pm
Re: FeatherM0 analogRead(A7) problem
The on board LED is next to Reset button on the M0 and is labelled CHG.
Yes, ironically I was just using the VBAT code to test the A/D and user interface, which was fine on the 32u4. I entered this cul de sac when porting 32u4 code to the M0, so ditching the A7 input is not a show stopper. My entire system will be powered by 12VDC, so I will just run a divider off of that and wire it to another analog input.
Probably a good idea to update the docs on both the M0 and OLED pages.
Thanks for you help!
Cliff
Yes, ironically I was just using the VBAT code to test the A/D and user interface, which was fine on the 32u4. I entered this cul de sac when porting 32u4 code to the M0, so ditching the A7 input is not a show stopper. My entire system will be powered by 12VDC, so I will just run a divider off of that and wire it to another analog input.
Probably a good idea to update the docs on both the M0 and OLED pages.
Thanks for you help!
Cliff
- adafruit_support_carter
- Posts: 29167
- Joined: Tue Nov 29, 2016 2:45 pm
Re: FeatherM0 analogRead(A7) problem
Will pass this along. May be worth making the guide(s) more explicit about potential interference between D9 and the battery sense. It's there, but kind of implicit and terse.
FWIW, the guides do mention the correct analog inputs for the battery sense and have proper example code.
For 32u4 (A9):
https://learn.adafruit.com/adafruit-fea ... ng-battery
and the M0 (A7):
https://learn.adafruit.com/adafruit-fea ... ng-battery
so if porting from 32u4 to M0, at a minimum you'd need to change that in the code. But doesn't fix the problem with being tied to D9, so:
FWIW, the guides do mention the correct analog inputs for the battery sense and have proper example code.
For 32u4 (A9):
https://learn.adafruit.com/adafruit-fea ... ng-battery
and the M0 (A7):
https://learn.adafruit.com/adafruit-fea ... ng-battery
so if porting from 32u4 to M0, at a minimum you'd need to change that in the code. But doesn't fix the problem with being tied to D9, so:
seems like a good solution for your setup.I will just run a divider off of that and wire it to another analog input.
Please be positive and constructive with your questions and comments.