funny A/D channel readings with Bobuino-1284 ???

Would someone please double check this. I tried reading the A/D channels of the
mega1284 loaded with the Bobuino variant of optiboot, and the channel numbering
seems to be offset by one position.

The complete sketch is given below. First off, it steps through analogRead() using
A0..A7 as channel parameter, and then repeats using 0..7. The results are shown
here, edited to show inputs. IE, with voltages on pins 33&34 [supposed to be ADC
channels 0 and 1, the levels end up on channel positions 1 and 2. Similarly, with
voltage applied at pin 40 [defined as ADC 7], the level shows up on channel position
0. The other readings are just noise, since the pins are not terminated.

What is wrong here?

1284 Analog Test ...
defines: A0=14, A7=21

pin 33=0V, pin 34=5V

A0..A7: 524 0 1023 774 611 524 457 417
0...7: 437 0 1023 875 747 638 555 492
A0..A7: 349 0 1023 793 622 529 460 426
0...7: 402 0 1023 880 756 646 566 508

pin 40=0V

A0..A7: 0 131 236 272 296 326 348 340
0...7: 0 131 234 274 296 319 342 336
A0..A7: 0 129 234 265 284 314 345 349
0...7: 0 107 202 242 267 293 314 324

/**********************************************************
file: analog_test1284 
revised: 01/21/13, orig 01/21/13.
 
Tests Bobuino-1284 ADC channels.
***********************************************************/

/**** Variables ****/
const int ledPin = 13;
int ledState = LOW;        
long interval = 500;  // blink interval (msec)
  
#define INTV   5000   // ADC repeat interval.
  
/*****************************************/
void setup() 
{       
  pinMode(ledPin, OUTPUT); 
  Serial.begin(57600);
  Serial.println("\n1284 Analog Test ...");

  a_print("defines: A0=",A0);
  a_print(", A7=",A7);
}

/******************************************/
void a_print( char *s, int num )
{
  Serial.print(s);  Serial.print(num);
}

/*****************************************************/
void loop() 
{
  schedule_blink();
  disp_adc();
}

/**************************************************/
void disp_adc()
{
  static unsigned long prev=0;   // last time LED was updated
  unsigned long current=millis();
  static int cnt=0;
  int i, val=0;
  
  if( (current - prev) > INTV) {
    prev = current;   // schedule next tick.
    nl();
    Serial.print("A0: ");   
    for( i=0; i<8; i++) {
      val = analogRead(A0+i);
      a_print(" ",val);
      delay(100);
    }
    nl(); 
    Serial.print(" 0: ");  
    for( i=0; i<8; i++) {
      val = analogRead(i);
      a_print(" ",val);
      delay(100);
    }
  }    
}

/*****************************************************/
void schedule_blink()
{
  static unsigned long prev=0;   // last time LED was updated
  unsigned long current=millis();
 
  if( (current - prev) > interval) {
    prev=current;       // save last time blinked the LED 

    // if the LED is off turn it on and vice-versa:
    if( ledState == LOW)  ledState = HIGH;
    else  ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void nl() {  Serial.println("");  }

Try doing 2 reads in a row, gives the voltage a chance to settle thru the multiplexer:

      val = analogRead(A0+i);
      val = analogRead(A0+i);
      a_print(" ",val);

Yeah, hi Bob, I had actually tried earlier reading the same channel multiple times,
and got the same result with the channels skewed.

The following is the result with the modified code shown below, and with the 0V and
5V applied to pin 40 only, which s/b A/D channel 7.

BTW, I'm not using your board, but have Bobuino-optiboot burned into a mega1284
chip, as mentioned on those 2 other recent threads.

all A0: 0 0 0 0 0 0 0 0
A0..A7: 0 134 233 264 283 313 340 352
0...7: 0 107 201 243 272 304 348 351

all A0: 1023 1023 1023 1023 1023 1023 1023 1023
A0..A7: 1023 803 653 528 448 413 403 393
0...7: 1023 887 783 670 575 517 478

 /**************************************************/
void disp_adc()
{
  static unsigned long prev=0;   // last time LED was updated
  unsigned long current=millis();
  static int cnt=0;
  int i, val=0;
  
  if( (current - prev) > INTV) {
    prev = current;   // schedule next tick.
    
    nl();
    Serial.print("all A0: ");   
    for( i=0; i<8; i++) {
      val = analogRead(A0);
      a_print(" ",val);
      delay(100);
    }    
    nl();
    Serial.print("A0..A7: ");   
    for( i=0; i<8; i++) {
      val = analogRead(A0+i);
      val = analogRead(A0+i);
      a_print(" ",val);
      delay(100);
    }
    nl(); 
    Serial.print(" 0...7: ");  
    for( i=0; i<8; i++) {
      val = analogRead(i);
      val = analogRead(i);
      a_print(" ",val);
      delay(100);
    }
  }    
}

I am thinking you are reading floating pins.
Instead of (A0 + i)
try putting the pins in an array, and use the array value as the selector

analogRead(analogArray[i]);

with the pins defined at the beginning of the sketch

analogArray[] = {0,1,2,3,4,5,6,7};

I dug up enough jumpers now to terminate all the unused A/D channels, and got this
with 5V,0V on pin 40. It's not a miswire on my protoboard, as I'm applying V straight
to the pin. I'll try your last idea.

all A0: 1023 1023 1023 1023 1023 1023 1023 1023
A0..A7: 1023 0 0 0 0 0 0 0
0...7: 1023 0 0 0 0 0 0 0

all A0: 0 0 0 0 0 0 0 0
A0..A7: 0 0 0 0 0 0 0 0
0...7: 0 0 0 0 0 0 0 0

Same thing with your code, V applied to pin 40.

0...7: 1023 0 0 0 0 0 0 0
0...7: 0 0 0 0 0 0 0 0

int analogArray[] = {0,1,2,3,4,5,6,7};

/**************************************************/
void disp_adc()
{
  static unsigned long prev=0;   // last time LED was updated
  unsigned long current=millis();
  static int cnt=0;
  int i, val=0;
  
  if( (current - prev) > INTV) {
    prev = current;   // schedule next tick.
    
    nl(); 
    Serial.print(" 0...7: ");  
    for( i=0; i<8; i++) {
      val=analogRead(analogArray[i]);
      a_print(" ",val);
      delay(100);
    }
  }    
}

At least I'm not having any problems whatsoever uploading sketches to the chip, like
the guys on the other threads, :-).

Well, that's what you want now, yes?
0 with jumpers to Gnd, and 1023 when pulled high?
Try the other pins with a pot from 0 to 5V and see that they follow the pot voltage.

I tried the pot on pins 40 and 39, modifying the channel scanned in the first loop,
and still works the same - ie, channels skewed. The last test, I used analogRead(21)
rather than analogRead(A7).

all A0, signal on pin 40: 0 0 68 465 733 935 1023 1023
A0..A7: 1023 0 0 0 0 0 0 0
0...7: 1023 0 0 0 0 0 0 0
all A0, signal on pin 40: 1023 1023 922 751 473 316 62 0
A0..A7: 0 0 0 0 0 0 0 0
0...7: 0 0 0 0 0 0 0 0

all A7, signal on pin 39: 0 208 635 899 1023 1023 1023 1023
A0..A7: 0 0 0 0 0 0 0 1023
0...7: 0 0 0 0 0 0 0 1023
all A7, signal on pin 39: 1023 1023 769 437 157 0 0 0
A0..A7: 0 0 0 0 0 0 0 0
0...7: 0 0 0 0 0 0 0 0

all 21, signal on pin 39: 0 196 298 309 591 756 893 1023
A0..A7: 0 0 0 0 0 0 0 1023
0...7: 0 0 0 0 0 0 0 1023
all 21, signal on pin 39: 1023 1023 868 628 342 128 0 0
A0..A7: 0 0 0 0 0 0 0 0
0...7: 0 0 0 0 0 0 0 0

BTW, I sent the following email to maniacbug ....

In your files from here,
Arduino on ATmega1284P | maniacbug

could you check in the arduino_pins.h file for the Bobuino variant bootloader if
the following line

#define analogPinToChannel(p) ( (p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) : -1 )

should read as

#define analogPinToChannel(p) ( (p) < NUM_ANALOG_INPUTS ? (NUM_ANALOG_INPUTS-1) - (p) : -1 )

Thanks. I'd really appreciate it - been spending days trying to get this chip in line.

I don't know if maniacbug is going to respond, but I'm 99% sure this is the problem.
The bootloader is configured wrong. I changed that line, and reburned the Bobuino
optiboot into my chip, and it works correctly now.

Is that from the bootloader, or from pins_arduino.h for the 1284?

I don't think I ever tried the analog inputs, I've only been using the digital pins.

oric_dan:
I don't know if maniacbug is going to respond, but I'm 99% sure this is the problem.
The bootloader is configured wrong. I changed that line, and reburned the Bobuino
optiboot into my chip, and it works correctly now.

What does the bootloader have to do with analog pin number assignments?

pins_arduino.h is used when compiling a sketch only.

Lefty

My mistake about this info being burned into the bootloader - I'm still trying to
sort out all the #defines and customization files and avrdudes and IDE folders,
on and on.

However, what I did was modify the file indicated in the previous post,

arduino_pins.h file for the Bobuino variant bootloader

located in the Arduino sketch folder under
..\Arduino\hardware\mighty-1284p-master\variants\bobuino

Would be nice if someone else could check this.

Working on college financial aid application the next couple of nights, don't think I can get to it very soon. It is amazing the level they dig into - much more pervasive than doing annual tax returns.

oric_dan:
My mistake about this info being burned into the bootloader - I'm still trying to
sort out all the #defines and customization files and avrdudes and IDE folders,
on and on.

However, what I did was modify the file indicated in the previous post,

arduino_pins.h file for the Bobuino variant bootloader

located in the Arduino sketch folder under
..\Arduino\hardware\mighty-1284p-master\variants\bobuino

Would be nice if someone else could check this.

Check what? That is the folder (\bobuino) where the 'custom' pins_arduino.h file needs to be located for the bobuino variant board version.

Lefty

Would you check whether the problem talked about on this thread is real, or if I
only dreamed it?

Eg, put a voltage on one of the A/D channels of the Bobuino 1284 bootloader chip
and then try to read it using analogRead().

oric_dan:
Would you check whether the problem talked about on this thread is real, or if I
only dreamed it?

Eg, put a voltage on one of the A/D channels of the Bobuino 1284 bootloader chip
and then try to read it using analogRead().

Yes, it seems to be messed up with or without the proposed changes to pins_arduino.h file you suggested.

I'll post what my pins read Vs what pins they should read a little later, have to go pick up wife at her
art lessons.

Lefty

OK, I'm using a 644P chip with the bobuino variant pins_arduino.h file being used. So using the example sketch Basics/AnalogReadSerial, I tried each analog channel number using both their Ax value and their digital pin alias (14-21) I got the following results:

sketch software pin name used valid voltage reading shows up on shield pin

A0 (or14) A1 (15)
A1 (or15) A0 (14)
A2 (or16) A7 (21)
A3 (or17) A6 (20)
A4 (or18) A5 (19)
A5 (or19) A4 (18)
A6 (or20) A3 (17)
A7 (or21) A2 (16)

I tested the digital pin numbers using digitalRead command and sending them out the serial port and manipulated the pins with a ground after having enabled their internal pull-ups, and see no problem, pin mapping is correct for Bobuino D0 through D31 for digitalRead commands.

So the problem seems to be in the mapping of the analog channels numbers 0-7 to the correct digital pin numbers. Or maybe the mapping is correct but the analog mux selection bits are backwards or something?

Lefty

Variant pins_arduino.h file being used

#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include <avr/pgmspace.h>

// ATMEL ATMEGA1284P on Bobuino
//
//                       +---\/---+
//           (D 4) PB0 1 |        | 40 PA0 (D 21) AI 7
//           (D 5) PB1 2 |        | 39 PA1 (D 20) AI 6
//      INT2 (D 6) PB2 3 |        | 38 PA2 (D 19) AI 5
//       PWM (D 7) PB3 4 |        | 37 PA3 (D 18) AI 4
//   PWM/SS (D 10) PB4 5 |        | 36 PA4 (D 17) AI 3
//     MOSI (D 11) PB5 6 |        | 35 PA5 (D 16) AI 2
// PWM/MISO (D 12) PB6 7 |        | 34 PA6 (D 15) AI 1
//  PWM/SCK (D 13) PB7 8 |        | 33 PA7 (D 14) AI 0
//                 RST 9 |        | 32 AREF
//                VCC 10 |        | 31 GND 
//                GND 11 |        | 30 AVCC
//              XTAL2 12 |        | 29 PC7 (D 29) 
//              XTAL1 13 |        | 28 PC6 (D 28) 
//      RX0 (D 0) PD0 14 |        | 27 PC5 (D 27) TDI
//      TX0 (D 1) PD1 15 |        | 26 PC4 (D 26) TDO
// INT0 RX1 (D 2) PD2 16 |        | 25 PC3 (D 25) TMS
// INT1 TX1 (D 3) PD3 17 |        | 24 PC2 (D 24) TCK
//     PWM (D 30) PD4 18 |        | 23 PC1 (D 23) SDA
//      PWM (D 8) PD5 19 |        | 22 PC0 (D 22) SCL
//      PWM (D 9) PD6 20 |        | 21 PD7 (D 31) PWM
//                       +--------+
//

#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8
#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 21 - (p) : -1)
extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];
extern const uint16_t __pcmsk[];
extern const uint8_t digital_pin_to_timer_PGM[NUM_DIGITAL_PINS];

#define ifpin(p,what,ifnot)	    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (what) : (ifnot))
#define digitalPinHasPWM(p)         ifpin(p,pgm_read_byte(digital_pin_to_timer_PGM + (p)) != NOT_ON_TIMER,1==0)

#define digitalPinToAnalogPin(p)    ( (p) >= 14 && (p) <= 21 ? (p) - 14 : -1 )
#define analogPinToChannel(p)	    ( (p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) : -1 )

static const uint8_t SS   = 10;
static const uint8_t MOSI = 11;
static const uint8_t MISO = 12;
static const uint8_t SCK  = 13;

static const uint8_t SDA = 23;
static const uint8_t SCL = 22;
static const uint8_t LED = 13;

static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;

#define digitalPinToPCICR(p)    ifpin(p,&PCICR,(uint8_t *)0)
#define digitalPinToPCICRbit(p) ifpin(p,digital_pin_to_pcint[p] >> 3,(uint8_t *)0)
#define digitalPinToPCMSK(p)    ifpin(p,__pcmsk[digital_pin_to_pcint[]],(uint8_t *)0)
#define digitalPinToPCMSKbit(p) ifpin(p,digital_pin_to_pcint[p] & 0x7,(uint8_t *)0)

#ifdef ARDUINO_MAIN

#define PA 1
#define PB 2
#define PC 3
#define PD 4

const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS] =
{
  24, // D0 PD0
  25, // D1 PD1
  26, // D2 PD2
  27, // D3 PD3
  8, // D4 PB0
  9, // D5 PB1
  10, // D6 PB2
  11, // D7 PB3
  29, // D8 PD5
  30, // D9 PD6
  12, // D10 PB4
  13, // D11 PB5
  14, // D12 PB6
  15, // D13 PB7
  7, // D14 PA7
  6, // D15 PA6
  5, // D16 PA5
  4, // D17 PA4
  3, // D18 PA3
  2, // D19 PA2
  1, // D20 PA1
  0, // D21 PA0
  16, // D22 PC0
  17, // D23 PC1
  18, // D24 PC2
  19, // D25 PC3
  20, // D26 PC4
  21, // D27 PC5
  22, // D28 PC6
  23, // D29 PC7
  28, // D30 PD4
  31, // D31 PD7
};

const uint16_t __pcmsk[] = 
{
  (uint16_t)&PCMSK0, 
  (uint16_t)&PCMSK1, 
  (uint16_t)&PCMSK2, 
  (uint16_t)&PCMSK3
};

// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &DDRA,
	(uint16_t) &DDRB,
	(uint16_t) &DDRC,
	(uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &PORTA,
	(uint16_t) &PORTB,
	(uint16_t) &PORTC,
	(uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &PINA,
	(uint16_t) &PINB,
	(uint16_t) &PINC,
	(uint16_t) &PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[NUM_DIGITAL_PINS] =
{
  PD, // D0
  PD, // D1
  PD, // D2
  PD, // D3
  PB, // D4
  PB, // D5
  PB, // D6
  PB, // D7
  PD, // D8
  PD, // D9
  PB, // D10
  PB, // D11
  PB, // D12
  PB, // D13
  PA, // D14
  PA, // D15
  PA, // D16
  PA, // D17
  PA, // D18
  PA, // D19
  PA, // D20
  PA, // D21
  PC, // D22
  PC, // D23
  PC, // D24
  PC, // D25
  PC, // D26
  PC, // D27
  PC, // D28
  PC, // D29
  PD, // D30
  PD, // D31
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[NUM_DIGITAL_PINS] =
{
  _BV(0), // D0 PD0
  _BV(1), // D1 PD1
  _BV(2), // D2 PD2
  _BV(3), // D3 PD3
  _BV(0), // D4 PB0
  _BV(1), // D5 PB1
  _BV(2), // D6 PB2
  _BV(3), // D7 PB3
  _BV(5), // D8 PD5
  _BV(6), // D9 PD6
  _BV(4), // D10 PB4
  _BV(5), // D11 PB5
  _BV(6), // D12 PB6
  _BV(7), // D13 PB7
  _BV(7), // D14 PA7
  _BV(6), // D15 PA6
  _BV(5), // D16 PA5
  _BV(4), // D17 PA4
  _BV(3), // D18 PA3
  _BV(2), // D19 PA2
  _BV(1), // D20 PA1
  _BV(0), // D21 PA0
  _BV(0), // D22 PC0
  _BV(1), // D23 PC1
  _BV(2), // D24 PC2
  _BV(3), // D25 PC3
  _BV(4), // D26 PC4
  _BV(5), // D27 PC5
  _BV(6), // D28 PC6
  _BV(7), // D29 PC7
  _BV(4), // D30 PD4
  _BV(7), // D31 PD7
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[NUM_DIGITAL_PINS] =
{
  NOT_ON_TIMER, // D0 PD0
  NOT_ON_TIMER, // D1 PD1
  NOT_ON_TIMER, // D2 PD2
  NOT_ON_TIMER, // D3 PD3
  NOT_ON_TIMER, // D4 PB0
  NOT_ON_TIMER, // D5 PB1
  NOT_ON_TIMER, // D6 PB2
  TIMER0A, // D7 PB3
  TIMER1A, // D8 PD5
  TIMER2B, // D9 PD6
  TIMER0B, // D10 PB4
  NOT_ON_TIMER, // D11 PB5
  TIMER3A, // D12 PB6
  TIMER3B, // D13 PB7
  NOT_ON_TIMER, // D14 PA0
  NOT_ON_TIMER, // D15 PA1
  NOT_ON_TIMER, // D16 PA2
  NOT_ON_TIMER, // D17 PA3
  NOT_ON_TIMER, // D18 PA4
  NOT_ON_TIMER, // D19 PA5
  NOT_ON_TIMER, // D20 PA6
  NOT_ON_TIMER, // D21 PA7
  NOT_ON_TIMER, // D22 PC0
  NOT_ON_TIMER, // D23 PC1
  NOT_ON_TIMER, // D24 PC2
  NOT_ON_TIMER, // D25 PC3
  NOT_ON_TIMER, // D26 PC4
  NOT_ON_TIMER, // D27 PC5
  NOT_ON_TIMER, // D28 PC6
  NOT_ON_TIMER, // D29 PC7
  TIMER1B, // D30 PD4
  TIMER2A, // D31 PD7
};

#endif // ARDUINO_MAIN

#endif // Pins_Arduino_h
// vim:ai:cin:sts=2 sw=2 ft=cpp

I had earlier checked the signals going to digital pins D0..D31, and they all matched
ok. However, try changing to the following line in Bobuino variant pins_arduino.h,

#define analogPinToChannel(p)   ( (p) < NUM_ANALOG_INPUTS ? 
  (NUM_ANALOG_INPUTS-1) - (p) : -1 )

The original produces 8..1 for p=0..7, while this one produces 7..0 for p=0..7.

oric_dan:
I had earlier checked the signals going to digital pins D0..D31, and they all matched
ok. However, try changing to the following line in Bobuino variant pins_arduino.h,

#define analogPinToChannel(p)   ( (p) < NUM_ANALOG_INPUTS ? 

(NUM_ANALOG_INPUTS-1) - (p) : -1 )




The original produces 8..1 for p=0..7, while this one produces 7..0 for p=0..7.

That made no change to the results of prior test, same weird ordering. However this ugly hack does fix it if using just the Ax name, but of course doesn't fix using the digital pin number work correctly.

static const uint8_t A0 = 15;
static const uint8_t A1 = 14;
static const uint8_t A2 = 21;
static const uint8_t A3 = 20;
static const uint8_t A4 = 19;
static const uint8_t A5 = 18;
static const uint8_t A6 = 17;
static const uint8_t A7 = 16;

Lefty