Author Topic: ATtiny13 project problems  (Read 9906 times)

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
ATtiny13 project problems
« on: May 18, 2014, 09:40:17 am »
I've written the following program, it takes an analogue reading off a temperature sensor and produces PWM accordingly. I'm getting nothing from it even if I comment out most of the code and just leave the PWM duty setting (last two lines).

I've used a lot of functions that I've included below and they are just to tray and keep the code rational and one day I'll reuse the functions in other programs once they work ;)

Code: [Select]
#define F_CPU 4800000UL
#include <avr/io.h>
#include "attiny13.h"


uint16_t T;    //Temperature reading
uint8_t D;     //Duty out setting
uint16_t Ton = 323; //cut in/out temperature
uint16_t Tset = 124;//Temperature at which ramp starts
uint16_t wait_time = 5000;

int main(void)
{


bit_s (DDRB, PB0); //pin 0 is digital output for PWM

vreff_vcc();
ch0();
adc_clk_div8();
adc_on();

fast_pwm_a();

    while(1)
    {
        T = adc_result();

if (T>Ton);
D = 255;

if ((T > Tset) && (T < Ton)) // speed for when temperature is between min and set temperature
D = 204;

if (T < Tset) //if over t set map speed to temperature
D = map(T, 66, 124, 25, 127);

if (T < 66) //if temp reads under -30 assume probe disconnected and run full speed
D = 13;

pwm_a_duty(D);

delay_ms(wait_time);

    }
}

Sections from the attiny13.h used are as follows:

Code: [Select]
#define bit_get(p,m) ((p) & (m))
#define bit_s(p,m) ((p) |= (m))
#define bit_c(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m)) // p is the register, m is the bit name
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))

Code: [Select]
void delay_ms(int ms) // millisecond delay function to use when the time is a variable and not a constant
{
while (ms--)
_delay_us(1000);
}

Code: [Select]
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Code: [Select]
void dO (int port, int pin) // make the pin a digital output, port and pin being the port name and pin name
{
bit_s (port, pin);
}

void dI (int port, int pin) // make the pin a digital input, port and pin being the port name and pin name
{
bit_c (port, pin);
}

Code: [Select]
void vreff_vcc (void)
{
bit_c (ADMUX, REFS0);
}

void ch0 (void)
{
bit_c (ADMUX, MUX1);
bit_c (ADMUX, MUX0);
bit_s (DIDR0, ADC0D);
}

void adc_clk_div8 (void)
{
bit_c (ADCSRA, ADPS2);
bit_s (ADCSRA, ADPS1);
bit_s (ADCSRA, ADPS0);
}

void adc_on (void)
{
bit_s (ADCSRA, ADEN);
}

Code: [Select]
void fast_pwm_a (void) //fast non inverted pwm with no prescaler
{

dO (DDRB, PB0);

bit_s (TCCR0A, COM0A1); //set pin as clear on match set on top
bit_c (TCCR0A, COM0A0);

bit_c (TCCR0A, WGM02); //fast pwm mode set
bit_s (TCCR0A, WGM01);
bit_s (TCCR0A, WGM00);

bit_c (TCCR0A, CS02); // no prescaler
bit_c (TCCR0A, CS01);
bit_s (TCCR0A, CS00);


}

void pwm_a_duty (uint8_t duty_a)
{
OCR0A = duty_a ;
}

 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: ATtiny13 project problems
« Reply #1 on: May 18, 2014, 09:53:19 am »
That "if" statement does nothing because it's terminated by a semicolon before any statement.
So D = 255; becomes a separate statement which will always execute.
So pwm is always 255  (100% high)


Code: [Select]

    ...
if (T>Ton);
D = 255;

...

pwm_a_duty(D);

...
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #2 on: May 18, 2014, 09:54:43 am »
ah, brilliant, thank you, although the output is actually always 0 but that surely needs correcting, I'll see what happens
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: ATtiny13 project problems
« Reply #3 on: May 18, 2014, 09:56:59 am »
Change   pwm_a_duty(D);      to      "pwm_a_duty(128);     and see if you get a square wave on the output.
That will atleast check if the pwm part of it is working.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #4 on: May 18, 2014, 10:04:02 am »
Hm, still nothing
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: ATtiny13 project problems
« Reply #5 on: May 18, 2014, 10:11:46 am »
PB0 shares the function of MOSI,
Is the PB0 pin being pulled High/Low by your programmer at all?  It should either be connected with a resistor or your programmer should be set to go highZ during non-programming (run) state.

If your programmer is always source/sinking the MOSI signal it will prevent the MCU from switching that output by shorting it.  ie output connected to output
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #6 on: May 18, 2014, 10:12:49 am »
Yes i thought of that and have been removing the programmer when running the circuit.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: ATtiny13 project problems
« Reply #7 on: May 18, 2014, 10:24:11 am »
I think your problem is in the use of those macros

Have a look at what this "bit set" macro is doing
#define    bit_s(p,m)     ((p) |= (m))

And then have a look at how its being used.

bit_s (DIDR0, ADC0D);

If we expand the macro we get

DIDR0  |= ADC0D;

The problem here is that ADC0D is defined as the bit position, not the value.
eg, ADC0D is defined as 5  ( bit 5 of DIDR0 )

so you are going
DIDR0  |= 5;
when you really want
DIDR0  |= 32;   // 0010 0000

You need to change the macro or how you are calling it.

My syntax knowledge of C macros is limited but you could..

Call it like this..
bit_s (DIDR0, (1<<ADC0D) );

OR, instead, change the macro too..
#define    bit_s(p,m)     ((p) |= (1<<(m)))


Note: other macros have the same usage problem, not just that one.
« Last Edit: May 18, 2014, 10:34:23 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #8 on: May 18, 2014, 10:42:08 am »
I think you are right, I should be using the BIT(x) macro as well and using it in conjunction with those macros.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: ATtiny13 project problems
« Reply #9 on: May 18, 2014, 10:43:37 am »
Yes, that would be another option.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #10 on: May 18, 2014, 10:45:19 am »
it's my stupid dyslexic brain, that is why i wrote the functions in the first place to save me making errors over and over again but this is the first time i use these on this chip so have only just written my header file.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #11 on: May 18, 2014, 02:08:52 pm »
Still no joy, I'll re trawl through the datasheet to see if I've gotten the functions right in the first place and try breadboarding it.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: ATtiny13 project problems
« Reply #12 on: May 18, 2014, 02:20:08 pm »
What voltage does the chip run on? Atmel chips in general (yes that is all of them: controllers, memory, etc) don't run reliably on the lowest voltage mentioned in the datasheet.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #13 on: May 18, 2014, 02:26:47 pm »
5 Volts
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #14 on: May 18, 2014, 03:12:55 pm »
ok sorted, I had used the wrong register name to setup the PWM mode, where I should have named register B I used A for everything so some register settings were just not happening.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #15 on: May 18, 2014, 03:45:46 pm »
although I'm yet to see the ADC bit of it work.
 

Offline Neverther

  • Regular Contributor
  • *
  • Posts: 129
Re: ATtiny13 project problems
« Reply #16 on: May 18, 2014, 04:49:31 pm »
I assume you want the ADC freerunning?
I dont see ADSC anywhere (ADC start conversion) or ADATE (ADC auto trigger).

Sample code of t13a running some fans to full on startup, then back off to pot setup ratio (usually so low they wouldnt start if it was fixed PWM).
0.83$ per chip so dont go all 555 preaching.
Code: [Select]
#ifndef F_CPU
#define F_CPU 9600000UL // CLOCKDIV8 OFF
#endif
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{

// PB4 is analog in + left adjust
ADMUX=(1<<MUX1) | (1<<ADLAR);
// ADC on and /64 -> 150kHz
ADCSRA=(1<<ADEN) | (1<<ADPS1) | (1<<ADPS2) | (1<<ADATE) | (1<<ADSC);
// Disable buffer
DIDR0=(1<<ADC2D);

// PB0 is PWM
DDRB=(1<<DDB0);
// Clear on compare match set on TOP and setup Fast PWM
TCCR0A=(1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
// Setup PWM freq /64
TCCR0B=(1<<CS00);

OCR0A = 0xFF;
_delay_ms(2000);
OCR0A = ADCH;

while(1) {
        _delay_ms(200);
        OCR0A = ADCH;
}
}
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1989
  • Country: dk
Re: ATtiny13 project problems
« Reply #17 on: May 18, 2014, 05:01:17 pm »
although I'm yet to see the ADC bit of it work.

Simon you'd need something like this (this is for a M32 though)


Code: [Select]

#define ADC_ENABLE (1<<ADEN)
#define ADC_CONVERT (1<<ADSC)
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0))
#define ADC_PRESCALE_128 ((1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)) //150 us Conversion time @11.xxx Mhz


void initadc(void){

ADCSRA = 0;
ADMUX = ADC_VREF_TYPE; //AVCC voltage reference with external capacitor at AREF pin
ADCSRA = ADC_ENABLE | ADC_PRESCALE_128 ; // ADC Enable and Set Prescale value
SFIOR &= 0x0F; // Make sure reserved bit 0x04 is set to zero

}



uint16_t read_adc(uint8_t adc_input)
{
ADMUX = adc_input|ADC_VREF_TYPE; // Internal 2.56 VREF , use the specified input pin
ADCSRA |= ADC_CONVERT; // ADC Start conversion (this bit is restored to zero when finished)
while (ADCSRA & ADC_CONVERT);     // Check the complete flag and wait until done
return ADCW;

}

The    while (ADCSRA & ADC_CONVERT);  is important


Taken from an old demo i made
http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_type=project&item_id=391


Edit: Also have a look here
http://www.adnbr.co.uk/articles/adc-and-pwm-basics


/Bingo
« Last Edit: May 18, 2014, 05:08:34 pm by bingo600 »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #18 on: May 18, 2014, 05:09:18 pm »
I assume you want the ADC freerunning?
I dont see ADSC anywhere (ADC start conversion) or ADATE (ADC auto trigger).

Sample code of t13a running some fans to full on startup, then back off to pot setup ratio (usually so low they wouldnt start if it was fixed PWM).
0.83$ per chip so dont go all 555 preaching.
Code: [Select]
#ifndef F_CPU
#define F_CPU 9600000UL // CLOCKDIV8 OFF
#endif
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{

// PB4 is analog in + left adjust
ADMUX=(1<<MUX1) | (1<<ADLAR);
// ADC on and /64 -> 150kHz
ADCSRA=(1<<ADEN) | (1<<ADPS1) | (1<<ADPS2) | (1<<ADATE) | (1<<ADSC);
// Disable buffer
DIDR0=(1<<ADC2D);

// PB0 is PWM
DDRB=(1<<DDB0);
// Clear on compare match set on TOP and setup Fast PWM
TCCR0A=(1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
// Setup PWM freq /64
TCCR0B=(1<<CS00);

OCR0A = 0xFF;
_delay_ms(2000);
OCR0A = ADCH;

while(1) {
        _delay_ms(200);
        OCR0A = ADCH;
}
}

Code: [Select]
int16_t adc_result (void) //return the current ADC value, the function will wait until the a conversion has ended.
{
uint16_t result;

while( ADCSRA & (1<<ADSC));   // Wait until ADC conversion is complete..

result = ADCW;

return result;
}

What I meant was i had not tested to see if the ADC code was working. The function above should run the adc and get a result much like the arduino adc read function.

I'm getting a waveform but I'm not quite sure if it's all tickety boo yet, this was originally written for the arduino on a Tiny25/85 but i made a mistake and put a tiny13 on the PCB which i was thinking of using anyhow so decided to rewrite in AVC for the 13 rather than 25/85
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #19 on: May 18, 2014, 05:18:27 pm »


Sample code of t13a running some fans to full on startup, then back off to pot setup ratio (usually so low they wouldnt start if it was fixed PWM).
0.83$ per chip so dont go all 555 preaching.


Haha, well what I am doing could be almost done with a potentiometer, the fans circuitry is actually low pass filtering the PWM input to a DC voltage so a thermistor and resistor in series with the output off the middle can do it crudely but I'm not going to tell my boss and potential customer that and it is already understood that I can change the parameters for them on demand and do anything else fancy that is allowable within the hardware.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #20 on: May 18, 2014, 05:51:20 pm »
ok so I'm getting a waveform and it is being generated by the program in some way but not as expected. My only assumption can be that the value is not being read properly from the ADCW register someone convinced me to use.........
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1989
  • Country: dk
Re: ATtiny13 project problems
« Reply #21 on: May 18, 2014, 06:01:23 pm »


Simon this http://www.adnbr.co.uk/articles/adc-and-pwm-basics

Suggests the register name is ADC on a T13 , not ADCW

I think that page is nice for a T13.

Are you running 9.6Mhz ? or the factory default ?

/Bingo

/Bingo
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #22 on: May 18, 2014, 06:03:30 pm »
ok I'll try ADC, I'm running 4.8MHz with no scaling
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: ATtiny13 project problems
« Reply #23 on: May 18, 2014, 06:10:52 pm »
It makes no difference with ADC, the tutorial you link to just uses ADCL in 8 bit mode, I am not doing this because i am not passing the ADC result straight to the ADC but working with it to come up with a PWM value so i need that resolution.
 

Offline Neverther

  • Regular Contributor
  • *
  • Posts: 129
Re: ATtiny13 project problems
« Reply #24 on: May 18, 2014, 06:20:46 pm »
Code: [Select]
while( ADCSRA & (1<<ADSC));   // Wait until ADC conversion is complete.
Please look at the datasheet, page 94.
You need to write into the register, then check if it is still set (single conversion mode).
Now you just check the register, but don't write into it to start the actual conversion.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf