go_away

Author Topic: Hardware PWM and ADC ATMega168 - Webbotlib  (Read 2111 times)

0 Members and 1 Guest are viewing this topic.

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Hardware PWM and ADC ATMega168 - Webbotlib
« on: June 28, 2010, 05:14:49 PM »
I have finished building the $50 robot microcontroller, and have started programming using Win AVR and the Webbot lib. The microcontroller is a ATMega168

I have got 3 hs-311 servos and made several photoresistors as per the tutorial.

Using Win AVR (omg so many things need improving and debugging) i have started testing Servos and ADC.

in Webbot's example he uses hardware PWM; i have had to use software PWM because there was no response from the servo with hardware PWM...

Code: [Select]
#include "sys/atmega168.h"
#include "servos.h"

#include "a2d.h"
 
// Define two light sensors connected to ADC channels 0 and 1
#define sensorLeft ADC_NUMBER_TO_CHANNEL(5)
//#define sensorRight ADC_NUMBER_TO_CHANNEL(1)
 
// Define two servos
SERVO left = MAKE_SERVO(FALSE, D0,1500, 500);
SERVO right = MAKE_SERVO(TRUE , D1,1500, 500);
 
// Create the list - remember to place an & at the
// start of each servo name
SERVO_LIST servos[] = {&left,&right};
 
// Create a driver for the list of servos
SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servos);
 
//the larger this number, the more likely your robot will drive straight
//#define threshold 8
 
// In my initialising code - pass the list of servos to control
void appInitHardware(void)
{
    // Initialise the servo controller
    servoPWMInit(&bank1);
    // Give each servo a start value of 'stop'
    act_setSpeed(&left, 0);
    act_setSpeed(&right,0);
}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart)
{
    return 0;
}
 
// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart)
{
//uint8_t lightLeft = a2dConvert8bit(sensorLeft);

//if(lightLeft < 100000)
//{
act_setSpeed(&left, 20);
act_setSpeed(&right,-50);
//}
    return 20000; // wait for 20ms to stop crazy oscillations
}

Any ideas on why the hardware PWM doesnt work?

Also the ADC is not responding as expected.

for instance; i have now used a potentiometer, with the wiper connected to the signal line, to test the ADC, even though my voltmeter reads a range of 5v, the values range from 65 ~ 150 only.
Note: i dont have a 0.1uf cap between VREF and AVCC, which the tutorial suggests i should do.
also i have connected the photoresistors which only give a range from 60 ~ 70, even when i change the reference resistor.

I will post the code i use for the ADC if anyone needs it. (The code is taken directly from Webbots photovore example)

Thanks Webbot for the library

Thanks in advance for any help ;)

T

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,152
  • Helpful? 110
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #1 on: June 28, 2010, 07:13:57 PM »
Your code snippet uses hardware PWM (ie it calls servoPWMInit) but the servos are on port D0 and D1 which, on an ATMega168, do not support hardware PWM - hence no response.

Try using B1 and B2 instead

Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #2 on: June 29, 2010, 03:39:24 PM »
Thanks Webbot!

how can you tell from the datasheet, which pins support hardware PWM and which dont?

Any ideas about the ADC thing?

Thanks for everyones help

T

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,663
  • Helpful? 169
    • Society of Robots
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #3 on: June 29, 2010, 04:55:43 PM »
For the ADC, can you describe your schematic for the pot better? I'm confused how you're wiring it . . .

how can you tell from the datasheet, which pins support hardware PWM and which dont?
The pin will have OC[number][letter] next to it, for example OC3A which means timer 3 on channel A.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,152
  • Helpful? 110
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #4 on: June 29, 2010, 06:44:50 PM »
how can you tell from the datasheet, which pins support hardware PWM and which dont?

Well the easiest way is to use my Project Designer - free download from my website http://webbot.org.uk
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #5 on: June 30, 2010, 03:40:04 AM »
Looking at the pinout, pins; 5, 11, 12, 15, 16 and 17 have hardware PWM so theres lots of choice,

Thanks guys :)

RE: Pot

The pot is connected as seen in the picture, this gives the voltage across (red to black) as a constant and allows the yellow to vary.


Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,663
  • Helpful? 169
    • Society of Robots
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #6 on: June 30, 2010, 07:18:51 AM »
Disconnect the pot, and then measure the change in resistance as you rotate the pot (between ground and output). Also, what is the ground to 5V resistance of the pot?

Quote
even though my voltmeter reads a range of 5v, the values range from 65 ~ 150 only.
What you mean is that you measured a full change from 0V to 5V, but when you rprintf the output you're getting only 65 to 150? (just to clarify)

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #7 on: July 01, 2010, 11:13:47 AM »
The resistance across the pot is 8.5k ohm, and the resistance varies linearly as the pot is turned, from ~0 ohm to 8.5k ohm.

i have to save the values to eeprom because i dont have a serial cable, the code for that is:
Code: [Select]

#include "sys/atmega168.h"

#include "a2d.h"

#define sensorLeft ADC_NUMBER_TO_CHANNEL(0)

uint8_t EEMEM myVar[500];

float Divide = 1.0;
int Looping = 1;
int Delay = 1;

int loop = -1;

// In my initialising code - pass the list of servos to control
void appInitHardware(void)
{
//Irrelevant code here

}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart)
{
    return 0;
}
 
// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart)
{
        if (Looping < 200)
        {
        Divide = a2dConvert8bit(sensorLeft);
        eeprom_write_byte(&myVar[Looping], Divide);
        Looping++;
        }

pin_high(B1);
delay_cycles(50000);
pin_low(B1);

loop++;

Delay = 1000 * Divide;
delay_cycles(Delay);

    return 2000; // wait for 20ms to stop crazy oscillations
}

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,152
  • Helpful? 110
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #8 on: July 01, 2010, 09:12:18 PM »
If you cant connect the board to the PC, only EEPROM, then how do you know what the values are that have been read from the ADC ?
ie how do you then dump the values from EEPROM to anything ?
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #9 on: July 02, 2010, 05:28:03 AM »
Sorry, i can connect the board to the pc with the AVR ISP MKII, so i can run the code, then collect the data.
In the example above, the LED flashing time is meant to vary with the potentiometer.

 

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,663
  • Helpful? 169
    • Society of Robots
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #10 on: July 02, 2010, 07:06:07 AM »
In the example above, the LED flashing time is meant to vary with the potentiometer.
int Delay = 1;
Delay = 1000 * Divide;

There is at least one of your bugs :P

change int to uint16_t

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,152
  • Helpful? 110
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #11 on: July 02, 2010, 08:01:54 AM »
It may also be a good idea to stop flashing the LED once you've filled up the array.
You will then see how long it takes to fill up the array. It could be that it is filled up so quickly that you haven't had a chance to turn the pot !

Alternatively use the first  two elements of your array to store the minimum and maximum adc values and keep updating those even after the rest of the array has been filled up.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #12 on: July 03, 2010, 08:20:16 AM »
I have changed the int to uint16_t which has seemed to have made little difference.
i setup the code to activate an LED whenever a reading was taken and i have confirmed that the ADC is read about 1 time per second
Having made sure the voltages are varying correctly with my voltmeter, i varied the pot full swing over about 30 seconds and got the readings to be all in the range of 101 to 109.

This is my revised code:
Code: [Select]
#include "sys/atmega168.h"

#include "a2d.h"

#define sensorLeft ADC_NUMBER_TO_CHANNEL(0)

uint8_t EEMEM myVar[500];

float Divide = 1.0;
uint32_t Delay = 1;
int Looping = 0;

// In my initialising code - pass the list of servos to control
void appInitHardware(void)
{
pin_make_output(B1);
pin_make_output(B2);
while (Looping < 500)
{
eeprom_write_byte(&myVar[Looping], 0);
Looping++;
}
Looping = 0;

}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart)
{
    return 0;
}
 
// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart)
{


if (Looping < 200)
        {
pin_high(B2);
        Divide = a2dConvert8bit(sensorLeft);
        eeprom_write_byte(&myVar[Looping], Divide);
        Looping++;
delay_cycles(500);
pin_low(B2);
        }


pin_high(B1);
delay_cycles(5000);
pin_low(B1);

if (Divide > 100)
{
Delay = 100000 * (Divide - 100);
}
else
{
Delay = 100000;
}

delay_cycles(Delay);


    return 20; // wait for 20ms to stop crazy oscillations
}

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #13 on: July 03, 2010, 02:43:13 PM »
Update:

I have disconnected all the IO's from the pins, i then ran this slightly updated version of the code (see below) to capture the inputs.
They were almost identical to the inputs i got from having the potentiometer.

this means i have got some hardware thing wrong...
what happens if the cap between AVCC and GND is broken?

FYI, pins B1 and B2 have LED's on them

Code: [Select]
#include "sys/atmega168.h"

#include "a2d.h"

#define sensorLeft ADC_NUMBER_TO_CHANNEL(0)

uint8_t EEMEM myVar[250];

uint8_t Divide = 1.0;
//uint32_t Delay = 1;
int Looping = 0;

// In my initialising code - pass the list of servos to control
void appInitHardware(void)
{
pin_make_output(B1);
pin_make_output(B2);
pin_high(B1);
while (Looping < 250)
{
eeprom_write_byte(&myVar[Looping], 0);
Looping++;
}
Looping = 0;
pin_low(B1);

}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart)
{
    return 0;
}
 
// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart)
{

if (Looping < 200)
        {
pin_high(B2);
        Divide = a2dConvert8bit(sensorLeft);
        eeprom_write_byte(&myVar[Looping], Divide);
        Looping++;
delay_cycles(5000);
pin_low(B2);
        }

pin_high(B1);
delay_cycles(5000);
pin_low(B1);

delay_cycles(100000);


    return 1; // wait for 20ms to stop crazy oscillations
}

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,663
  • Helpful? 169
    • Society of Robots
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #14 on: July 04, 2010, 09:07:28 AM »
You do have AVCC connected to VCC, right?

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #15 on: July 05, 2010, 05:49:04 AM »
Yeah i do, i have rechecked the circuit several times and its all good, the only thing i can think of would be the software, maybe the registers are incorrectly set.

i have checked the other ADC channels with nothing connected, i get similar results to   using ADC channel 0, except these go between 120 and 135.

would high res photos help?

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,152
  • Helpful? 110
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #16 on: July 05, 2010, 11:35:48 AM »
.... the only thing i can think of would be the software, maybe the registers are incorrectly set.....
Lots of other folk are using the ADC stuff either directly or indirectly when they read sensors.

You really need to get a MAX232 type level shifter so that you can send stuff back to the PC. There are just too many possible error points here.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline totalisTopic starter

  • Full Member
  • ***
  • Posts: 89
  • Helpful? 0
Re: Hardware PWM and ADC ATMega168 - Webbotlib
« Reply #17 on: July 05, 2010, 03:40:40 PM »
I wouldnt think to blame it on your software, simply my version of it.

i have got a MAX232 shifter coming from SmAsH so i will report back when i have it.

thanks for all the help everyone

T

 


Get Your Ad Here