Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

New good solution for C programmers?

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
29 postsPage 2 of 21, 2
29 postsPage 2 of 21, 2

Post by Kess » Wed Feb 13, 2008 11:18 pm

Post by Kess
Wed Feb 13, 2008 11:18 pm

Hi again,

My ADC reading code (which uses the 5V supply as the ADC reference) is as follows:

Code: Select all
unsigned ReadADC(byte channel)
{
    ADMUX  = 0x40 | channel;
    ADCSRA = 0xC6;
    while(bit_is_set(ADCSRA, ADSC));
    return (ADCL | (ADCH<<8));
}


This works for me. I call the function with the parameter set to 0 to read ADC0 (the battery +ve voltage) or 1 to read ADC1 (the battery -ve voltage). My test program has a simple loop that continuously reads and displays the two ADCs and allows me to enable or disable charging by pressing the buttons on the CM-5.

A couple of other things:

- The actual battery voltage is equal to the data from ADC0 or ADC1 multiplied by 0.01968 (this factor allows for the resistive potential dividers in the circuit as well as the 5V reference voltage etc.). However, if you simply double the ADC data you'll get a result that gives voltage in 10mV steps (e.g. a result of 1250 means 12.50 volts) and is less than 2% in error.

- Battery charging is controlled by PORTB pin PB5. Charging is activated by setting PB5 to 0 and disabled by setting PB5 to 1. Charging progress can be monitored by watching the voltage on ADC1, which creeps downwards as the battery gets charged; I guess the "official" charging code disables charging once the rate of change on ADC1 drops below a certain rate.

Hope that helps,
Kess
Hi again,

My ADC reading code (which uses the 5V supply as the ADC reference) is as follows:

Code: Select all
unsigned ReadADC(byte channel)
{
    ADMUX  = 0x40 | channel;
    ADCSRA = 0xC6;
    while(bit_is_set(ADCSRA, ADSC));
    return (ADCL | (ADCH<<8));
}


This works for me. I call the function with the parameter set to 0 to read ADC0 (the battery +ve voltage) or 1 to read ADC1 (the battery -ve voltage). My test program has a simple loop that continuously reads and displays the two ADCs and allows me to enable or disable charging by pressing the buttons on the CM-5.

A couple of other things:

- The actual battery voltage is equal to the data from ADC0 or ADC1 multiplied by 0.01968 (this factor allows for the resistive potential dividers in the circuit as well as the 5V reference voltage etc.). However, if you simply double the ADC data you'll get a result that gives voltage in 10mV steps (e.g. a result of 1250 means 12.50 volts) and is less than 2% in error.

- Battery charging is controlled by PORTB pin PB5. Charging is activated by setting PB5 to 0 and disabled by setting PB5 to 1. Charging progress can be monitored by watching the voltage on ADC1, which creeps downwards as the battery gets charged; I guess the "official" charging code disables charging once the rate of change on ADC1 drops below a certain rate.

Hope that helps,
Kess
Kess
Robot Builder
Robot Builder
Posts: 18
Joined: Sun Nov 18, 2007 7:56 pm
Location: The Cotswolds, UK

Post by pieddemamouth » Thu Feb 14, 2008 7:44 am

Post by pieddemamouth
Thu Feb 14, 2008 7:44 am

Thanks for your code.
I will test it this week-end and aware you of the results
Thanks for your code.
I will test it this week-end and aware you of the results
pieddemamouth
Robot Builder
Robot Builder
Posts: 12
Joined: Sun Feb 10, 2008 6:17 pm

Post by siempre.aprendiendo » Thu Feb 14, 2008 2:12 pm

Post by siempre.aprendiendo
Thu Feb 14, 2008 2:12 pm

Wow, thank you very much, Kess

I will try it asap :)

P.S.
As Lego with Mindstorms changed their "policy" form RCX to NXT, from non public information about hardware and software to open source "policy", publishing all the information, included source code, of their Mindstorms NXT product, I hope that Robotis would take a similar path.

I think that an open source policy will allow create software more easily than now, adding more value to Bioloid. At least with Mindstorms, the grow have been impressive from RCX, for example, more than 10 books about NXT in less than a year and half

(Please, excuse my English :roll: )
Wow, thank you very much, Kess

I will try it asap :)

P.S.
As Lego with Mindstorms changed their "policy" form RCX to NXT, from non public information about hardware and software to open source "policy", publishing all the information, included source code, of their Mindstorms NXT product, I hope that Robotis would take a similar path.

I think that an open source policy will allow create software more easily than now, adding more value to Bioloid. At least with Mindstorms, the grow have been impressive from RCX, for example, more than 10 books about NXT in less than a year and half

(Please, excuse my English :roll: )
siempre.aprendiendo
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 559
Joined: Wed Aug 08, 2007 9:13 pm
Location: Barcelona

Post by pieddemamouth » Sun Feb 17, 2008 3:49 pm

Post by pieddemamouth
Sun Feb 17, 2008 3:49 pm

Hi,

I've try your code Kess, and it works on my bioloid to. But I don't understand some of your configuration's choice :
- Why did you have choose "AVCC with external capacitor at AREF pin" for the voltage reference ? In one of your post you have said :
One other thing you guys may need to know is that the processor's AREF pin (pin 62), which provides the reference voltage for the ADC, is connected directly to the +5V rail.

So I have use "AREF, Internal Vref turned off" for the voltage reference.
- Why did you have selected the "ADC Prescaler". To my mind it's useless, we want the ADC result asap.

Thanks for your responses.
Hi,

I've try your code Kess, and it works on my bioloid to. But I don't understand some of your configuration's choice :
- Why did you have choose "AVCC with external capacitor at AREF pin" for the voltage reference ? In one of your post you have said :
One other thing you guys may need to know is that the processor's AREF pin (pin 62), which provides the reference voltage for the ADC, is connected directly to the +5V rail.

So I have use "AREF, Internal Vref turned off" for the voltage reference.
- Why did you have selected the "ADC Prescaler". To my mind it's useless, we want the ADC result asap.

Thanks for your responses.
pieddemamouth
Robot Builder
Robot Builder
Posts: 12
Joined: Sun Feb 10, 2008 6:17 pm

Post by Kess » Mon Feb 18, 2008 9:40 pm

Post by Kess
Mon Feb 18, 2008 9:40 pm

pieddemamouth wrote:Why did you have choose "AVCC with external capacitor at AREF pin" for the voltage reference ... I have use "AREF, Internal Vref turned off" for the voltage reference.

Since the AREF pin is connected to AVCC you can use either setting, it should give the same result.
- Why did you have selected the "ADC Prescaler". To my mind it's useless, we want the ADC result asap.

The ADC can't be run at the full 16MHz processor clock speed - some prescaling is essential. According to the Atmel data sheet:
By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.

My prescaler setting of 6 gives a divide-by-64 so the ADC clock rate will be 125kHz.

Out of interest I just tried adding a second ADC routine to my test code with a different prescaler setting, displaying the results of the two routines. A prescaler setting of 5 (divide-by-32) seems to work fine, even though the 250kHz ADC clock speed is slightly higher than recommended, but a prescaler setting of 4 (divide-by-16) or less gives jittery results.

I wouldn't worry about speeding up the ADC conversion, however, as voltage doesn't change very quickly. It would be better to modify the ADC routine to prevent the processor having to wait for the result, e.g. use an interrupt to grab the result from the ADC when it's ready, or simply allow the processor to go away and do some other stuff and come back for the result later. My little ADC routine can definitely be improved...

Kess
pieddemamouth wrote:Why did you have choose "AVCC with external capacitor at AREF pin" for the voltage reference ... I have use "AREF, Internal Vref turned off" for the voltage reference.

Since the AREF pin is connected to AVCC you can use either setting, it should give the same result.
- Why did you have selected the "ADC Prescaler". To my mind it's useless, we want the ADC result asap.

The ADC can't be run at the full 16MHz processor clock speed - some prescaling is essential. According to the Atmel data sheet:
By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.

My prescaler setting of 6 gives a divide-by-64 so the ADC clock rate will be 125kHz.

Out of interest I just tried adding a second ADC routine to my test code with a different prescaler setting, displaying the results of the two routines. A prescaler setting of 5 (divide-by-32) seems to work fine, even though the 250kHz ADC clock speed is slightly higher than recommended, but a prescaler setting of 4 (divide-by-16) or less gives jittery results.

I wouldn't worry about speeding up the ADC conversion, however, as voltage doesn't change very quickly. It would be better to modify the ADC routine to prevent the processor having to wait for the result, e.g. use an interrupt to grab the result from the ADC when it's ready, or simply allow the processor to go away and do some other stuff and come back for the result later. My little ADC routine can definitely be improved...

Kess
Kess
Robot Builder
Robot Builder
Posts: 18
Joined: Sun Nov 18, 2007 7:56 pm
Location: The Cotswolds, UK

Post by pieddemamouth » Mon Feb 18, 2008 10:44 pm

Post by pieddemamouth
Mon Feb 18, 2008 10:44 pm

Thanks for your reply.
Now, i know why my code didn't work.

See you
Thanks for your reply.
Now, i know why my code didn't work.

See you
pieddemamouth
Robot Builder
Robot Builder
Posts: 12
Joined: Sun Feb 10, 2008 6:17 pm

Post by bergere » Wed Mar 12, 2008 4:11 pm

Post by bergere
Wed Mar 12, 2008 4:11 pm

Are there any news about Loading the Batteries?
Need a programm! :P
Are there any news about Loading the Batteries?
Need a programm! :P
bergere
Savvy Roboteer
Savvy Roboteer
Posts: 28
Joined: Thu Nov 29, 2007 10:18 pm

Post by pieddemamouth » Wed Mar 12, 2008 7:54 pm

Post by pieddemamouth
Wed Mar 12, 2008 7:54 pm

Hi,

Kess has give a programm at the top of this page. isn't it what you need ?
Hi,

Kess has give a programm at the top of this page. isn't it what you need ?
pieddemamouth
Robot Builder
Robot Builder
Posts: 12
Joined: Sun Feb 10, 2008 6:17 pm

Post by bergere » Mon Mar 17, 2008 9:53 am

Post by bergere
Mon Mar 17, 2008 9:53 am

I tried it again and know the batteries loading.
My mistake was that i forget the following function.
Code: Select all
if(!(DDRB &(1<<5))) DDRB |=(1<<5);


I don´t know if I understand this function completly.

if(DDRB!=1)then{DDRB=1}???

And the output of Kess function give me the following Output.

33/609...33/609...32/610... are this correct Output values? (I think you know it if you test the programm, too)
I tried it again and know the batteries loading.
My mistake was that i forget the following function.
Code: Select all
if(!(DDRB &(1<<5))) DDRB |=(1<<5);


I don´t know if I understand this function completly.

if(DDRB!=1)then{DDRB=1}???

And the output of Kess function give me the following Output.

33/609...33/609...32/610... are this correct Output values? (I think you know it if you test the programm, too)
bergere
Savvy Roboteer
Savvy Roboteer
Posts: 28
Joined: Thu Nov 29, 2007 10:18 pm

Post by pieddemamouth » Mon Mar 17, 2008 6:33 pm

Post by pieddemamouth
Mon Mar 17, 2008 6:33 pm

Personaly, my code for charging is :
Code: Select all
PORTB &= ~PB5;


I haven't use my bioloid for a while, so I don't remember exactly my last test. But I have done as Kess as said : doubled the value and display it (value in mV). Here is my code for displaying :
Code: Select all
int main(void) {
    CM5_init();
    unsigned int i=1, retour,condition=0;

    PORTE |= _BV(PE4);    //enable pull-up resistor 4
    EIMSK |= _BV(INT4);   //enable interrupt 4
    DDRC = 0xFF;
    PORTC = 0xFF;
    DDRB |= _BV(DDB5);  //output for bit PB5

    //ADC configuration
    ADMUX = 0x10;
    ADCSRA = 0x80;

    while(1)
    {
            CM5_RS232_writeString("\rTension batterie : ");
            retour = ReadADC(16);
            retour = retour*2;
            CM5_RS232_writeHexInt(retour);
            CM5_RS232_writeString("\n\r");
    }
}
Personaly, my code for charging is :
Code: Select all
PORTB &= ~PB5;


I haven't use my bioloid for a while, so I don't remember exactly my last test. But I have done as Kess as said : doubled the value and display it (value in mV). Here is my code for displaying :
Code: Select all
int main(void) {
    CM5_init();
    unsigned int i=1, retour,condition=0;

    PORTE |= _BV(PE4);    //enable pull-up resistor 4
    EIMSK |= _BV(INT4);   //enable interrupt 4
    DDRC = 0xFF;
    PORTC = 0xFF;
    DDRB |= _BV(DDB5);  //output for bit PB5

    //ADC configuration
    ADMUX = 0x10;
    ADCSRA = 0x80;

    while(1)
    {
            CM5_RS232_writeString("\rTension batterie : ");
            retour = ReadADC(16);
            retour = retour*2;
            CM5_RS232_writeHexInt(retour);
            CM5_RS232_writeString("\n\r");
    }
}
pieddemamouth
Robot Builder
Robot Builder
Posts: 12
Joined: Sun Feb 10, 2008 6:17 pm

Post by Kess » Mon Mar 17, 2008 8:45 pm

Post by Kess
Mon Mar 17, 2008 8:45 pm

Hi Bergere,

Your numbers of 32/610 look about right; assuming those are the raw ADC data values from ADC1 and ADC0 then they equate to about 0.64V for the battery -ve and 12.2V for the battery +ve.

During charging the lower number should get smaller and eventually stop changing. At that point the battery is full and you should disable the charging - please be careful not to overcharge the battery!

Kess
Hi Bergere,

Your numbers of 32/610 look about right; assuming those are the raw ADC data values from ADC1 and ADC0 then they equate to about 0.64V for the battery -ve and 12.2V for the battery +ve.

During charging the lower number should get smaller and eventually stop changing. At that point the battery is full and you should disable the charging - please be careful not to overcharge the battery!

Kess
Kess
Robot Builder
Robot Builder
Posts: 18
Joined: Sun Nov 18, 2007 7:56 pm
Location: The Cotswolds, UK

Post by bergere » Fri Apr 04, 2008 10:38 am

Post by bergere
Fri Apr 04, 2008 10:38 am

Thx, but I think it´s to late.
After charging CM-5 the Buttons on the top are pushed permanent. I loaded my software on another CM-5 and it works fine. Is it possible that this is a effect of overcharging?
Thx, but I think it´s to late.
After charging CM-5 the Buttons on the top are pushed permanent. I loaded my software on another CM-5 and it works fine. Is it possible that this is a effect of overcharging?
Für Fehler und Schrift haftet der Stift. Palim Palim
bergere
Savvy Roboteer
Savvy Roboteer
Posts: 28
Joined: Thu Nov 29, 2007 10:18 pm

Post by Kess » Sat Apr 05, 2008 10:46 pm

Post by Kess
Sat Apr 05, 2008 10:46 pm

Sorry, I'm not sure what you mean by "the buttons are pushed permanent". If one or more of the buttons on your CM-5 have stuck down then I don't see how this could be caused by overcharging - none of the buttons are directly connected to the charging circuit.

The pushbuttons are small switches mounted on the printed circuit board beneath the plastic buttons - see http://robosavvy.com/Builders/Kess/CM5_PCB_Rear_1.jpg . I don't know if you have any experience of electronics but you could open up your CM-5 and use a multimeter to check the resistance of each the switches and see if any is permanently closed.
Sorry, I'm not sure what you mean by "the buttons are pushed permanent". If one or more of the buttons on your CM-5 have stuck down then I don't see how this could be caused by overcharging - none of the buttons are directly connected to the charging circuit.

The pushbuttons are small switches mounted on the printed circuit board beneath the plastic buttons - see http://robosavvy.com/Builders/Kess/CM5_PCB_Rear_1.jpg . I don't know if you have any experience of electronics but you could open up your CM-5 and use a multimeter to check the resistance of each the switches and see if any is permanently closed.
Kess
Robot Builder
Robot Builder
Posts: 18
Joined: Sun Nov 18, 2007 7:56 pm
Location: The Cotswolds, UK

Post by cosa » Wed Apr 23, 2008 10:41 pm

Post by cosa
Wed Apr 23, 2008 10:41 pm

Hi,

I'm currently testing your code. It works fine: the battery is recharging and I'm measuring the change rate of ADC1. How small does the ADC1 value normally get? Atm it's at 200 and it only changes every ~80 seconds.

Edit: my test code (ADC1 is checked every 1000ms, 30 values are accumulated, the RECHARGEREMOVECYCLES largest and smallest value are removed and the average of the rest of the values is calculated. If the average hasn't changed from the last 30 second time frame a counter is increased. If this counter is larger than maxCycles the recharging ist aborted)

Code: Select all
// still testing
#define RECHARGECYCLES 30
#define RECHARGEREMOVECYCLES 4
#define RECHARGEPAUSE 100000
#define RECHARGEMAX 10 // 10 cycles a 30 seconds 5mins = 300 seconds without change in batterie voltage

// recharge batteries functions
// thanks to kess and pieddemamouth (robosavvy-forums)
unsigned int readADC(byte channel)
{
    ADMUX  = 0x40 | channel;
    ADCSRA = 0xC6;
    while(bit_is_set(ADCSRA, ADSC));
    return (ADCL | (ADCH<<8));
}

void rechargeBatteries(unsigned int maxCycles)
{
   // configuration
   cli();
   
   PORTE |= _BV(PE4);    //enable pull-up resistor 4
    EIMSK |= _BV(INT4);   //enable interrupt 4
    DDRC = 0xFF;
    PORTC = 0xFF;
    DDRB |= _BV(DDB5);  //output for bit PB5

    //ADC configuration
    ADMUX = 0x10;
    ADCSRA = 0x80;
   
    sei();
   
   unsigned int voltage[RECHARGECYCLES], voltageCounter, counter, average, oldAverage;
   byte buffer[8];
   int i,j;
   
   // enable charging
   PORTB &= ~PB5;
   
   counter = 0;
   voltageCounter = 0;
   average = 0;
   oldAverage = 10000;
   
   while (true)
   {
       voltage[voltageCounter] = readADC(1);
      voltage[voltageCounter] *= 2;
      voltageCounter++;
      
      if (voltageCounter >= RECHARGECYCLES)
      {
         voltageCounter = 0;
         
         // min sort
         unsigned int min;
         int minId;
         for (i=0; i<RECHARGECYCLES; i++)
         {
            min = voltage[i];
            minId = i;
            for (j=i+1; j<RECHARGECYCLES; j++)
               if (voltage[j] < min)
               {
                  minId = j;
                  min = voltage[j];
               }
               
            min = voltage[i];
            voltage[i] = voltage[minId];
            voltage[minId] = min;
         }
         
         // calc average (without REMOVECYCLES largest and smallest values)
         unsigned long int tmp = voltage[RECHARGECYCLES];
         for (i=RECHARGEREMOVECYCLES+1; i<RECHARGECYCLES-RECHARGEREMOVECYCLES; i++)
         {
               tmp += voltage[i];
         }
         
         double tmpf = (double) tmp / ((double)(RECHARGECYCLES-2*RECHARGEREMOVECYCLES));
         
         average = (unsigned int) (tmpf + 0.5);
         
         if (average >= oldAverage) // unchanged
            counter++;
         else
         {
            counter = 0; // reset counter if changed
            oldAverage = average;
         }
      }
      
      if (counter >= maxCycles)
      {
         buffer[0] = 0xFF;
         buffer[1] = 0xFF;
         buffer[2] = 0xFF;
         buffer[3] = 0xFF;
         buffer[4] = 0xFF;
         buffer[5] = 0xFF;
         buffer[6] = 0xFF;
         buffer[7] = 0xFF;
         writeData(buffer, 8);
         break;
      }   
         
      buffer[0] = voltage[(voltageCounter - 1) % RECHARGECYCLES]  & 0xFF;
      buffer[1] = (voltage[(voltageCounter - 1) % RECHARGECYCLES] ) >> 8;
      buffer[2] = average & 0xFF;
      buffer[3] = (average) >> 8;
      buffer[4] = counter & 0xFF;
      buffer[5] = (counter & 0xFF00) >> 8;
      buffer[6] = maxCycles & 0xFF;
      buffer[7] = (maxCycles & 0xFF00) >> 8;
      writeData(buffer, 8);
      
      sleep(RECHARGEPAUSE); //1000ms
   }
   
   // disable charging
   PORTB |= PB5;
}
Hi,

I'm currently testing your code. It works fine: the battery is recharging and I'm measuring the change rate of ADC1. How small does the ADC1 value normally get? Atm it's at 200 and it only changes every ~80 seconds.

Edit: my test code (ADC1 is checked every 1000ms, 30 values are accumulated, the RECHARGEREMOVECYCLES largest and smallest value are removed and the average of the rest of the values is calculated. If the average hasn't changed from the last 30 second time frame a counter is increased. If this counter is larger than maxCycles the recharging ist aborted)

Code: Select all
// still testing
#define RECHARGECYCLES 30
#define RECHARGEREMOVECYCLES 4
#define RECHARGEPAUSE 100000
#define RECHARGEMAX 10 // 10 cycles a 30 seconds 5mins = 300 seconds without change in batterie voltage

// recharge batteries functions
// thanks to kess and pieddemamouth (robosavvy-forums)
unsigned int readADC(byte channel)
{
    ADMUX  = 0x40 | channel;
    ADCSRA = 0xC6;
    while(bit_is_set(ADCSRA, ADSC));
    return (ADCL | (ADCH<<8));
}

void rechargeBatteries(unsigned int maxCycles)
{
   // configuration
   cli();
   
   PORTE |= _BV(PE4);    //enable pull-up resistor 4
    EIMSK |= _BV(INT4);   //enable interrupt 4
    DDRC = 0xFF;
    PORTC = 0xFF;
    DDRB |= _BV(DDB5);  //output for bit PB5

    //ADC configuration
    ADMUX = 0x10;
    ADCSRA = 0x80;
   
    sei();
   
   unsigned int voltage[RECHARGECYCLES], voltageCounter, counter, average, oldAverage;
   byte buffer[8];
   int i,j;
   
   // enable charging
   PORTB &= ~PB5;
   
   counter = 0;
   voltageCounter = 0;
   average = 0;
   oldAverage = 10000;
   
   while (true)
   {
       voltage[voltageCounter] = readADC(1);
      voltage[voltageCounter] *= 2;
      voltageCounter++;
      
      if (voltageCounter >= RECHARGECYCLES)
      {
         voltageCounter = 0;
         
         // min sort
         unsigned int min;
         int minId;
         for (i=0; i<RECHARGECYCLES; i++)
         {
            min = voltage[i];
            minId = i;
            for (j=i+1; j<RECHARGECYCLES; j++)
               if (voltage[j] < min)
               {
                  minId = j;
                  min = voltage[j];
               }
               
            min = voltage[i];
            voltage[i] = voltage[minId];
            voltage[minId] = min;
         }
         
         // calc average (without REMOVECYCLES largest and smallest values)
         unsigned long int tmp = voltage[RECHARGECYCLES];
         for (i=RECHARGEREMOVECYCLES+1; i<RECHARGECYCLES-RECHARGEREMOVECYCLES; i++)
         {
               tmp += voltage[i];
         }
         
         double tmpf = (double) tmp / ((double)(RECHARGECYCLES-2*RECHARGEREMOVECYCLES));
         
         average = (unsigned int) (tmpf + 0.5);
         
         if (average >= oldAverage) // unchanged
            counter++;
         else
         {
            counter = 0; // reset counter if changed
            oldAverage = average;
         }
      }
      
      if (counter >= maxCycles)
      {
         buffer[0] = 0xFF;
         buffer[1] = 0xFF;
         buffer[2] = 0xFF;
         buffer[3] = 0xFF;
         buffer[4] = 0xFF;
         buffer[5] = 0xFF;
         buffer[6] = 0xFF;
         buffer[7] = 0xFF;
         writeData(buffer, 8);
         break;
      }   
         
      buffer[0] = voltage[(voltageCounter - 1) % RECHARGECYCLES]  & 0xFF;
      buffer[1] = (voltage[(voltageCounter - 1) % RECHARGECYCLES] ) >> 8;
      buffer[2] = average & 0xFF;
      buffer[3] = (average) >> 8;
      buffer[4] = counter & 0xFF;
      buffer[5] = (counter & 0xFF00) >> 8;
      buffer[6] = maxCycles & 0xFF;
      buffer[7] = (maxCycles & 0xFF00) >> 8;
      writeData(buffer, 8);
      
      sleep(RECHARGEPAUSE); //1000ms
   }
   
   // disable charging
   PORTB |= PB5;
}
cosa
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 40
Joined: Mon Dec 04, 2006 1:00 am

Previous
29 postsPage 2 of 21, 2
29 postsPage 2 of 21, 2