Show multiplexed ADC data to virtual terminal on proteus (using codevision avr)

Go To Last Post
26 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi...

i have problem to show multiplexed 8 ADC data to virtual terminal or to LCD

the problem is i don't know how to do it ?

is there anyone can help

 

here is my code and schematic bitmap :


#include <mega16.h>

#include <delay.h>
#include <stdio.h>

// Alphanumeric LCD Module functions
#include <alcd.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
//#include <lcd.h>

#define ADC_VREF_TYPE 0x20

//#define ADC_VREF_TYPE 0x00

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here
float s1,s2,s3,s4,s5,s6,s7,s8;
//bit b1,b2,b3,b4,b5,b6,b7,b8;
unsigned char ts[16];

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out 
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0 
PORTB=0x0f; //0x00;
DDRB=0x0f; //0x07;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;



// ADC initialization
// ADC Clock frequency: 691.200 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: Free Running
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
SFIOR&=0x1F;

// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 8
lcd_init (16);//(8);

while (1)
      {
PORTB=0b00000000;s1=(float)read_adc(0);
PORTB=0b00000001;s2=(float)read_adc(0);
PORTB=0b00000010;s3=(float)read_adc(0);
PORTB=0b00000011;s4=(float)read_adc(0);
PORTB=0b00000100;s5=(float)read_adc(0);
PORTB=0b00000101;s6=(float)read_adc(0);
PORTB=0b00000110;s7=(float)read_adc(0);
PORTB=0b00000111;s8=(float)read_adc(0);
lcd_gotoxy(0,0);lcd_putsf("multiplex 4051?");
//sprintf(ts,"%d%d%d%d%d%d%d%d",s1,s2,s3,s4,s5,s6,s7,s8);
lcd_gotoxy(0,1);lcd_puts(ts);
      // Place your code here

      } ;
}

 

 

This topic has a solution.

Last Edited: Mon. Jan 26, 2015 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1)  Repost your code using the code formatting tag on the toolbar <> to preserve formatting.

2)  While the ADC multiplexer (4051) can certainly be useful, why did you decide on that approach instead of using the multiple ADC channels on the AVR itself?

3)  How do you expect to put eight floating-point numbers onto one 16-character LCD line?

4)  Why use float in the first place?  (Hint:  Until you get everything going properly, just get and display ADC counts.

 

But for an apparent first attempt, it doesn't look too bad.  The short delay in read_adc() should let the multiplexer settle.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NB:  If it were my app and I was just getting going, I'd display four ADC channel counts on each line, four characters each.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

1)  Repost your code using the code formatting tag on the toolbar <> to preserve formatting.

2)  While the ADC multiplexer (4051) can certainly be useful, why did you decide on that approach instead of using the multiple ADC channels on the AVR itself?

3)  How do you expect to put eight floating-point numbers onto one 16-character LCD line?

4)  Why use float in the first place?  (Hint:  Until you get everything going properly, just get and display ADC counts.

 

But for an apparent first attempt, it doesn't look too bad.  The short delay in read_adc() should let the multiplexer settle.

 

thanks, i have repost it

well, this is my homework on school to analyze ADC using 4051

but i dont know how to display it, on lcd and on virtual terminal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

NB:  If it were my app and I was just getting going, I'd display four ADC channel counts on each line, four characters each.

 

how to do that master ? can you tell me please

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you really write your code flush-left, with no indentation structure?

 

unsigned int s1,s2,s3,s4,s5,s6,s7,s8; // A/D counts
unsigned char ts[20]; // 16-character LCD line, null terminator, plus a few more
...
while (1)
    {
    PORTB=0b00000000;
    s1=read_adc(0);

    PORTB=0b00000001;
    s2=read_adc(0);
    
    PORTB=0b00000010;
    s3=read_adc(0);
    
    PORTB=0b00000011;
    s4=read_adc(0);
    
    PORTB=0b00000100;
    s5=read_adc(0);
    
    PORTB=0b00000101;
    s6=read_adc(0);
    
    PORTB=0b00000110;
    s7=read_adc(0);
    
    PORTB=0b00000111;
    s8=read_adc(0);

    sprintf (ts, "%4u%4u%4u%4u", s1, s2, s3, s4);
    lcd_gotoxy(0,0);
    lcd_puts(ts);

    sprintf (ts, "%4u%4u%4u%4u", s5, s6, s7, s8);
    lcd_gotoxy(0,1);
    lcd_puts(ts);
    }
    

 

Now, many of us would use an array...

 

unsigned int    result[8];  // A/D counts
unsigned char   looper;     // loop counter
unsigned char   temp;       // PORTB manipulations
unsigned char ts[20];       // 16-character LCD line, null terminator, plus a few more
...
while (1)
    {
    for (looper = 0; looper < 8; looper++)
        {
        temp = PORTB;
        temp &= ~0x07;
        temp |= looper;
        PORTB = temp; // set low 3 bits of PORTB to multiplexor selector
        
        result[looper] = read_adc(0);
        }

    sprintf (ts, "%4u%4u%4u%4u", result[0], result[1], result[2], result[3]);
    lcd_gotoxy(0,0);
    lcd_puts(ts);

    sprintf (ts, "%4u%4u%4u%4u", result[4], result[5], result[6], result[7]);
    lcd_gotoxy(0,1);
    lcd_puts(ts);
    }
    

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// ADC Clock frequency: 691.200 kHz

What does the datasheet say about recommended ADC clock rate?

 

// ADC Auto Trigger Source: Free Running

You do >>not<< want free-running; you want single-conversion mode.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

Do you really write your code flush-left, with no indentation structure?

 

 

 

unsigned int s1,s2,s3,s4,s5,s6,s7,s8; // A/D counts
unsigned char ts[20]; // 16-character LCD line, null terminator, plus a few more
...
while (1)
    {
    PORTB=0b00000000;
    s1=read_adc(0);

    PORTB=0b00000001;
    s2=read_adc(0);
    
    PORTB=0b00000010;
    s3=read_adc(0);
    
    PORTB=0b00000011;
    s4=read_adc(0);
    
    PORTB=0b00000100;
    s5=read_adc(0);
    
    PORTB=0b00000101;
    s6=read_adc(0);
    
    PORTB=0b00000110;
    s7=read_adc(0);
    
    PORTB=0b00000111;
    s8=read_adc(0);

    sprintf (ts, "%4u%4u%4u%4u", s1, s2, s3, s4);
    lcd_gotoxy(0,0);
    lcd_puts(ts);

    sprintf (ts, "%4u%4u%4u%4u", s5, s6, s7, s8);
    lcd_gotoxy(0,1);
    lcd_puts(ts);
    }
    

 

Now, many of us would use an array...

 

unsigned int    result[8];  // A/D counts
unsigned char   looper;     // loop counter
unsigned char   temp;       // PORTB manipulations
unsigned char ts[20];       // 16-character LCD line, null terminator, plus a few more
...
while (1)
    {
    for (looper = 0; looper < 8; looper++)
        {
        temp = PORTB;
        temp &= ~0x07;
        temp |= looper;
        PORTB = temp; // set low 3 bits of PORTB to multiplexor selector
        
        result[looper] = read_adc(0);
        }

    sprintf (ts, "%4u%4u%4u%4u", result[0], result[1], result[2], result[3]);
    lcd_gotoxy(0,0);
    lcd_puts(ts);

    sprintf (ts, "%4u%4u%4u%4u", result[4], result[5], result[6], result[7]);
    lcd_gotoxy(0,1);
    lcd_puts(ts);
    }
    

 

 

 

 

 

it's work... i use your second coding that use array

but the display make me confuse.. i can't mark which is analog 1-analog8 

 

this is what display when i turn the potensiometer number 1 untill zero% 

 

this is what display when i turn the potensiometer number 2 untill zero% 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i use your second coding that use array but the display make me confuse..

I'm confused as well...I'd like to see your code of the "second coding".  ADC counts can >>only<< be 0-1023.  The numbers you showed certainly don't fit into that range.

 

As for which channel is which--four per line, four characters each, starting from upper left.  Study the sprintf().

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why don't you just say that you have a 20x4 LCD ?

 

After all,   this is just a Proteus Simulation.

 

The other method is to write each channel:value one at a time to the LCD with perhaps a 1-second pause between each display.

 

I really don't see how you can get the LCD to display as in your images.

With Lee's code, I would expect something like:

 123 456 678 901
1023  54   9  12 

The ADCW is always going to be a number between 0 and 1023.    By the law of averages,   most of the readings will be 3-digits.   So you should have some spaces that do the padding.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

// ADC Clock frequency: 691.200 kHz

What does the datasheet say about recommended ADC clock rate?

 

// ADC Auto Trigger Source: Free Running

You do >>not<< want free-running; you want single-conversion mode.

 

 

 

according to the discussion here https://www.avrfreaks.net/forum/m...

i see that ADC clock is recommended at 1Mhz

but i use free running mode on codewizard avr that causing the ADC clock become 691.2kHz

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

i use your second coding that use array but the display make me confuse..

I'm confused as well...I'd like to see your code of the "second coding".  ADC counts can >>only<< be 0-1023.  The numbers you showed certainly don't fit into that range.

 

As for which channel is which--four per line, four characters each, starting from upper left.  Study the sprintf().

 

okey here it is

 

#include <mega16.h>

#include <delay.h>
#include <stdio.h>

// Alphanumeric LCD Module functions
#include <alcd.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
//#include <lcd.h>

#define ADC_VREF_TYPE 0x20

//#define ADC_VREF_TYPE 0x00

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{

unsigned int result[8];  // A/D counts 
unsigned char looper;     // loop counter
unsigned char temp;       // PORTB manipulations
unsigned char ts[20];       // 16-character LCD line, null terminator, plus a few more


// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out 
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0 
PORTB=0x0f; //0x00;
DDRB=0x0f; //0x07;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;



// ADC initialization
// ADC Clock frequency: 691.200 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: Free Running
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
SFIOR&=0x1F;

// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 8
lcd_init (16);//(8);

while (1)
      {

for (looper = 0; looper < 8; looper++)
        {
        temp = PORTB;
        temp &= ~0x07;
        temp |= looper;
        PORTB = temp; // set low 3 bits of PORTB to multiplexor selector
        
        result[looper] = read_adc(0);
        }

    sprintf (ts, "%4u%4u%4u%4u", result[0], result[1], result[2], result[3]);
    lcd_gotoxy(0,0);
    lcd_puts(ts);

    sprintf (ts, "%4u%4u%4u%4u", result[4], result[5], result[6], result[7]);
    lcd_gotoxy(0,1);
    lcd_puts(ts);
      } ;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

 

I really don't see how you can get the LCD to display as in your images.

With Lee's code, I would expect something like:

 123 456 678 901
1023  54   9  12 

The ADCW is always going to be a number between 0 and 1023.    By the law of averages,   most of the readings will be 3-digits.   So you should have some spaces that do the padding.

 

David.

 

yeah, i don't understand...

is this make effect ?

unsigned char ts[20];

is that make effect the display become like this

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

according to the discussion here https://www.avrfreaks.net/forum/max-adc-speed

What does the datasheet say? But no mind for your simulation.

 

Given your code, I can't explain it.  Perhaps a simulation artifact?  Ask the Proteus people?  When you turn a "pot" down, your previous results indicate things are tracking properly.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// Characters/line: 8
lcd_init (16);//(8);

???  You told CV you had  a 2x8 display, but then initialized for 16?

 

I told you to turn >>off<< free-running, but you have not.

 

65472 is -63.  I have no idea how that is coming through, from an ADCW read.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

according to the discussion here https://www.avrfreaks.net/forum/max-adc-speed

What does the datasheet say? But no mind for your simulation.

 

Given your code, I can't explain it.  Perhaps a simulation artifact?  Ask the Proteus people?  When you turn a "pot" down, your previous results indicate things are tracking properly.

 

 

i'm not found yet about recommended adc clock rate on atmega16 datasheet...but some text says if i use 200kHz adc clock frequency, it will take convertion time 65 microsecond & extended convertion will take 125 micro second... is it only affect the convertion time ???

 

when i turn a "pot"up, this happen :

pot 0% = 0V(voltmeter) = 0 (character on LCD)

pot 1% = 0.05V(voltmeter) = 640 (char on LCD)

pot 2% = 0.10V(voltmeter) = 1280(char on LCD)

|

|

pot 100% = 5V (voltmeter) = 65472(char on LCD)

 

i see it change linear.

so if i use the formula :

(1% pot) 640/65472 * 5V = 0.049V (0.05V measure by voltmeter)

and so the value :

(2% pot) 1280/65472*5V = 0.098V (0.10V measure by voltmeter)

 

so.. is it a matter of data type ???

because it should be show the range from 0 - 1023 bit not from 0 - 65472

 

but when i change the variable :

unsigned char ts[20];

with

unsigned int ts[20];

it is become error like this :

[192] function argument #1 of type 'unsigned int [20]' is incompatible with required parameter of type 'unsigned char *'
[192] sprintf (ts, "%4u%4u%4u%4u", result[0], result[1], result[2], result[3]);

 

please, is there something wrong with "sprintf" and "int" ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

please, is there something wrong with "sprintf" and "int" ?

I mentioned earlier--look to see how sprintf() works. The first parameter is a character buffer for the result of sprintf().

 

Please post you entire actual program that is getting your results.  My suspicion is that your program doesn't represent my sample code.

 

i'm not found yet about recommended adc clock rate on atmega16 datasheet...

 

By default, the successive approximation circuitry requires an input clock frequency between 50
kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the
input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define ADC_VREF_TYPE 0x20

//#define ADC_VREF_TYPE 0x00

What inspired you to first run the Wizard, and then bash the results?

 

Your change there sets ADLAR.  See the datasheet for what that is.  Yes, since you have left-shifted the result you will get your symptoms.  Don't use ADLAR unless you want 8-bit results.  Don't use free-running for what you are trying to do.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't believe you.    I copy-pasted the code that you posted earlier in msg#12

I configured <alcd.h> for PORTC according to your schematic.   (and the comments in your code)

 

And it compiled just fine.  Since it was 1916 bytes with CV v3.16,   you should have no problem with compiling with the free Evaluation Codevision.

void main(void)
{
    unsigned int result[8];     // A/D counts 
    unsigned char looper;       // loop counter
    unsigned char temp;         // PORTB manipulations
    unsigned char ts[20];       // 16-character LCD line, null terminator, plus a few more
    PORTB = 0x0f;               //0x00;
    DDRB = 0x0f;                //0x07;
    // ADC initialization
    // ADC Clock frequency: 691.200 kHz
    // ADC Voltage Reference: AREF pin
    // ADC Auto Trigger Source: Free Running
    ADMUX = ADC_VREF_TYPE & 0xff;
    ADCSRA = 0x84;
    SFIOR &= 0x1F;

    lcd_init(16);               //(8);

    while (1) {

        for (looper = 0; looper < 8; looper++) {
            temp = PORTB;
            temp &= ~0x07;
            temp |= looper;
            PORTB = temp;       // set low 3 bits of PORTB to multiplexor selector

            result[looper] = read_adc(0);
        }

        sprintf(ts, "%4u%4u%4u%4u", result[0], result[1], result[2], result[3]);
        lcd_gotoxy(0, 0);
        lcd_puts(ts);

        sprintf(ts, "%4u%4u%4u%4u", result[4], result[5], result[6], result[7]);
        lcd_gotoxy(0, 1);
        lcd_puts(ts);
    };
}

I really can't see how you could get 'negative' values from ADCW.   The read_adc() function looks fine.   In fact it looks unchanged from the CodeWizard.

 

Are you sure that your school has Proteus licences that are up to date?

Mind you,   the program should work fine with whatever binary that CV has generated.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I really can't see how you could get 'negative' values from ADCW. ...

Didja notice my post, mentioning how OP "improved" the Wizard code with a gratuitous setting of ADLAR?  That explains the big values... 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,  I noticed your post after I had finished my message.    I should have edited my post to reflect your solution.

 

Yes,  I agree.   It is unwise to kludge the code generated by the Wizard.    It is better to re-run the Wizard.   You get "accurate comments".

 

David.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You get "accurate comments".

Indeed.  For us with a "trained eye", it appeared to be Wizard code, and the Wizard-generated comments did not include 

// Voltage Reference: AREF pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (1<<ADLAR))

OP must be using an old CV version?  In 2.x, the Wizard would generate "#define ADC_VREF_TYPE 0x20" and the comment block:

 

// Only the 8 most significant bits of
// the AD conversion result are used

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

#define ADC_VREF_TYPE 0x20

//#define ADC_VREF_TYPE 0x00

What inspired you to first run the Wizard, and then bash the results?

 

Your change there sets ADLAR.  See the datasheet for what that is.  Yes, since you have left-shifted the result you will get your symptoms.  Don't use ADLAR unless you want 8-bit results.  Don't use free-running for what you are trying to do.

 

it works, thanks master..

yes i do mistake, i just try other people code without knowing what is it use for... that is my mistake...

and then i forgot to rewrite the code when i use new code referrence..

 

as your advice , i do this...


#define ADC_VREF_TYPE 0x00

 

and LCD display correct value

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
 

 

By default, the successive approximation circuitry requires an input clock frequency between 50
kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the
input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.

 

 

 

oooh.... is it affected the convertion time ?

how to measure the efffect of using analog multiplexer,

i can measure the switch time of AMUX by measure it from output of the analog multiplexer using digital oscilloscope tool like this :

 

 channel A to port control A AMUX

 channel B to port control B AMUX

 channel C to port control C AMUX

 channel D to port output AMUX

 

 

but it is not show graph from output of ATmega16... how can i measure it... ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps it's time to add a Proteus forum with homework answers section angel

 

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps it's time to add a Proteus forum with homework answers section angel

 

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...