Tiny85 PWM on 1.25 micro second ?

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

Guys,

 

How can I make a PWM signal for 1.25 us ?

 

 

The code I have made :

 

uint16_t b=0;
    //set timer 0 as Fast PWM
    TCCR0A|=(1<<WGM00)|(1<<WGM01)|(1<<COM0B1)|(0<<COM0B0);
    TCCR0B|=(1<<CS00);
    
    for(b=0;b<1024;b++)
    {
        //set brightness with PWM

        PWMOut_1(b);

        
        _delay_us(1);
    }
    
    _delay_ms(500);
    
    for(b=1024;b>0;b--)
    {
        //set brightness with PWM

        PWMOut_1(b);

        
        _delay_us(1);
    }
    
    _delay_ms(100);

Any ideas ?

 

Thanks in advance.....

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

Your question is not clear. It looks like you want to generate data for the ws2813 leds. So why use pwm?
You have a logic analyser - observe why your code doesn't work

Last Edited: Wed. Oct 14, 2015 - 09:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Here's how I do it

 

Attachment(s): 

Imagecraft compiler user

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

And of course there are these Threads on the WS2812B LED:

 

Here

 

and Here

 

JC

 

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

Ain't NeoPixels grand?   That's Lady Adafruit's name for the programmable sequencing LED/IC/modules called WS2812.  

 

You don't want to use PWM to control them because each cycle has a different duty cycle.  If all the cycles were the same duty cycle (the ratio of the high part to the low part of the logic pulse), then PWM would work fine.

 

Lady Adafruit has given us a NeoPixel library for Arduino that works rather well.  Its source code demonstrates how to integrate cycle-by-cycle hand-built assembler routines with standard C++ code.  You can cut-and-paste those routines into your own code if you're using Studio 6.

The advantage of arduino is that you can spend your creative energy thinking of what to do with your new microcontroller toys instead of on all the technical details of getting them to work at all.

 

By the way, what are you planning to do with these NeoPixels?  Since they are so bright I've set up six around small plastic solders and model airplanes.  Then I've set up white paper around them as a screen.  The strong ever-changing lights and colors coming from the LEDs create a version of Indonesian shadow puppet theater.

 

Another application of NeoPixels would be to have a dozen mounted on the back of a bicycle helmet.  The bicycles speedometer/trip computer would send (using BlueTooth) the bicycle's speed to an AVR on the helmet's top.  Then the bicyclist's speed would be displayed as a range of colors.  Going 5-10 MPH (8-14 kilometers-per-hour KPH) would light the LEDs orange.  Going 10-18 MPH would be green: 18-25 MPH (@30 KPH) would be blue: and faster than 25 MPH would be red.   That way the cars behind the bicyclist can know how fast he is going.  (it's a he because I'm assuming that any woman would be smart enough not to be riding a bicycle in traffic after dark).

 

So write again on this message steam to let us know what you've got your NeoPixels doing besides being Christmas tree lights.

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

The 70-post long thread I linked to above in #3 is >>his<<.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Thanks guys for the ideas, I'll give a try later on....

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

I got :

Error    10    undefined reference to `NOP'  ...

 

How to fix it guys ?

Thanks

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

Antonio - give us a better idea of what you're talking about! What code are you talking about? What compiler?

My guess - NOP()

 

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

Yes,

NOP();

 

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

What code are you talking about? What compiler?

 

The code :

#define T0H() NOP()

 

Compiler :

Atmel Studio 6.1

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

What transistor is recommended for driving 30 LEDs ? would 2N3904 be enough ? thanks

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

A 2N3904 is fine for driving the digital signal.

 

The WS2812B LEDs have a separate connection to V+ and Ground.

 

You control the brightness via the digital control signal, not by PWM the power to the LED itself.

 

For the digital signal the drive requirement is very low, and it doesn't matter how many are in the string, and each LED outputs a newly internally generated copy of the incoming digital signal.

 

JC

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

Are you compiling that program in msg 4 with avrstudio? The 3rd line at the top says what compiler I used to compile it, but I assume there is a way to write a c define to tell the atmel compiler to generate a no-op.

 

Imagecraft compiler user

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

Hi Bob...

 

I wrote :
 

#define F_CPU 16000000UL  // 16 MHz
#include <avr/io.h>
#include <avr/cpufunc.h>



unsigned char r,g,b;
//-------------------------
void initvars(void){
	//init vars

	r=0xc0;
	g=0xc0;
	b=0xc0;
}

void port_init(void){
	//mega328

	//PORTB = 0xFF;
	//DDRB  = 0xFF; //
	
   PORTD = 0xFF;
   DDRD  = 0xFF; //
	
}

//-------------------
void delnms(int n){
	//delay n ms
	int x;

	while(n--){
		//    x=2400;       //empirically determined fudge factor  14 mhz
		x=2600;       //empirically determined fudge factor  16 mhz
		//    x=2800;       //empirically determined fudge factor  18 mhz
		//    x=3000;       //empirically determined fudge factor  20 mhz
		while(x--);
	}
}

//-------------------
void delnus(int n){
	//delay n us
	int x;

	while(n--){
		x=3;       //empirically determined fudge factor  16 mhz
		while(x--);
	}
}


//---------WS2812 stuff------------------------
//specs:
//t0h .35us 5.6 cyc
//t0l .8    12.8
//t1h .7    11.2
//t1l .6    9.6

//16mhz = 62.5ns
//t0h+t0l=1.25us 8x1.25us=10us 800K bps
//1million sends should be 10sec
//this version is about 10 sec
//t0h .35us 5 cyc dh=2, 1nop dl=2
//t0l .8us  13 cyc tot= 8nops+5 for sbrs rjmp  20x62.5 = 1.25usec
//t1h .7us  11 cyc dh=2 7 nops dl=2
//t1l .6us  10 cyc tot=8nops+2 for rjmp

//

#define T0H() asm("nop");

//            8
//#define T0L() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T0L() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

//            7
//#define T1H() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T1H() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
//            8
//#define T1L() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T1L()asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

//2     1      2=5  +8=13+5 for sbrs and rjmp=21
#define SEND0() DH(); T0H(); DL(); T0L()

//            //2     7      2=11  +8+2 for rjmp=21
#define SEND1() DH(); T1H(); DL(); T1L()

 

but I didn't see any pulse in my logic analyzer, I'm using atmega128.....

Is there something missing ?

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

I try to drive 30 LEDs and the power supply is from USB port (USBasp), is it sufficient ? thanks

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

How many milliamps can each led ( or ws2812 draw)? Times by 30. Less than 500mA?
Datasheet says 20mA per led. 30 x 3 x 20
I think you'll need a power supply

Last Edited: Fri. Oct 23, 2015 - 11:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
How many milliamps can each led ( or ws2812 draw)? Times by 30. Less than 500mA? Datasheet says 20mA per led. 30 x 3 x 20 I think you'll need a power supply

1.8 VA.....I have a charger with 1VA...will it be enough for temporary test ?

 

I can see only 1 led on when I used a power from usbasp.........is it because of power supply ?

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

The complete code I use, taken from bob's example :

/*
 * GccApplication1.c
 *
 * Created: 18/10/2015 1:12:10 PM
 *  Author: antonius
 */ 

#define F_CPU 16000000UL  // 16 MHz
#include <avr/io.h>
#include <avr/cpufunc.h>



unsigned char r,g,b;
//-------------------------
void initvars(void){
	//init vars

	r=0xc0;
	g=0xc0;
	b=0xc0;
}

void port_init(void){
	//mega328

	//PORTB = 0xFF;
	//DDRB  = 0xFF; //
	
   PORTD = 0xFF;
   DDRD  = 0xFF; //
	
}

//-------------------
void delnms(int n){
	//delay n ms
	int x;

	while(n--){
		//    x=2400;       //empirically determined fudge factor  14 mhz
		x=2600;       //empirically determined fudge factor  16 mhz
		//    x=2800;       //empirically determined fudge factor  18 mhz
		//    x=3000;       //empirically determined fudge factor  20 mhz
		while(x--);
	}
}

//-------------------
void delnus(int n){
	//delay n us
	int x;

	while(n--){
		x=3;       //empirically determined fudge factor  16 mhz
		while(x--);
	}
}


//---------WS2812 stuff------------------------
//specs:
//t0h .35us 5.6 cyc
//t0l .8    12.8
//t1h .7    11.2
//t1l .6    9.6

//16mhz = 62.5ns
//t0h+t0l=1.25us 8x1.25us=10us 800K bps
//1million sends should be 10sec
//this version is about 10 sec
//t0h .35us 5 cyc dh=2, 1nop dl=2
//t0l .8us  13 cyc tot= 8nops+5 for sbrs rjmp  20x62.5 = 1.25usec
//t1h .7us  11 cyc dh=2 7 nops dl=2
//t1l .6us  10 cyc tot=8nops+2 for rjmp

//           2 cyc

//#define DL() PORTB &= ~0x01
//#define DH() PORTB |=  0x01

#define DL() PORTD &= ~0x01
#define DH() PORTD |=  0x01

//            1

//#define T0H() NOP()

#define T0H() asm("nop");

//            8
//#define T0L() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T0L() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

//            7
//#define T1H() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T1H() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
//            8
//#define T1L() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP()
#define T1L()asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

//2     1      2=5  +8=13+5 for sbrs and rjmp=21
#define SEND0() DH(); T0H(); DL(); T0L()

//            //2     7      2=11  +8+2 for rjmp=21
#define SEND1() DH(); T1H(); DL(); T1L()

//----------------------------
void res(void){
	//reset low for 50usec

	DL(); delnus(55);
}

//----------------------------
void send(unsigned char b){
	//send a byte in ws2812 format should take 8x1.25us->10usec
	unsigned char n;

	for(n=0x80; n>0; n>>=1){   //<---- change to 80 40 20 10 etc
		if(b & n){
			SEND1();
			}else{
			SEND0();
		}
	}//for
}

//------------------------------
void send30leds(void){
	//calls send 30 times
	unsigned char n;
	
	n=30;
	while(n--){
		send(g);
		send(r);
		send(b);
	}
	res();
}

//------------------------
void allon(void){
	r=g=b=0xff;
}

//------------------------
void alloff(void){
	r=g=b=0x00;
}

//------------------------
void allred(void){
	r=0xff;
	g=b=0x00;
}

//------------------------
void allgreen(void){
	g=0xff;
	r=b=0x00;
}

//------------------------
void allblue(void){
	b=0xff;
	r=g=0x00;
}

//------------------------
void fadeup(void){
	if(r < 255) r++;
	if(g < 255) g++;
	if(b < 255) b++;
}

//------------------------
void fadedn(void){
	if(r > 0) r--;
	if(g > 0) g--;
	if(b > 0) b--;
}

unsigned char rdat[30],gdat[30],bdat[30];
unsigned char ndx;
//------------------------------
void send30rgbs(void){
	//calls send 30 times
	unsigned char *pr;
	unsigned char *pg;
	unsigned char *pb;
	unsigned char n;

	pr=rdat; //init pointers
	pg=gdat;
	pb=bdat;
	n=30;
	while(n--){    //update 30 leds
		send(*pg++);
		send(*pb++);
		send(*pr++);
	}
	res();
}


//------------------------
void knightridercom(void){
	//one of 30 on
	unsigned char n;

	send30rgbs();

	for(n=0; n<30; n++){
		rdat[n]=gdat[n]=bdat[n]=0; //clear all
	}
	ndx++;
	if(ndx >= 30){
		ndx=0;
		for(n=0; n<30; n++){
			rdat[n]=gdat[n]=bdat[n]=0; //clear all
		}
		//		rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set first led
	}
	rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set next led
	delnms(50);
}

//------------------------
void knightriderrandcom(void){
	//one of 30 on
	unsigned char n;

	send30rgbs();

	for(n=0; n<30; n++){
		rdat[n]=gdat[n]=bdat[n]=0; //clear all
	}
	ndx++;
	if(ndx >= 30){
		ndx=0;
		for(n=0; n<30; n++){
			rdat[n]=gdat[n]=bdat[n]=0; //clear all
		}
		//		rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set first led
	}
	rdat[ndx]=rand()%255;
	gdat[ndx]=rand()%255;
	bdat[ndx]=rand()%255; //set next led
	delnms(50);
}

//------------------------
void knightriderloop(void){
	//one of 30 leds on in sequence 0 to 29
	unsigned char n,c;

	ndx=0;
	for(n=0; n<30; n++){
		rdat[n]=gdat[n]=bdat[n]=0; //clear
	}
	rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set first led
	c=0;
	while(c != 'q'){
		if(kbhit()){
			c=getchar();
		}
		knightridercom();
	}//while
}

//------------------------
void vucom(void){
	//grows from 0 until all on
	unsigned char n;

	send30rgbs();

	ndx++;
	if(ndx >= 30){
		ndx=0;
		for(n=0; n<30; n++){
			rdat[n]=gdat[n]=bdat[n]=0; //clear
		}
	}
	rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set next
	delnms(50);
}

//------------------------
void vuloop(void){
	//grows from 0
	unsigned char c,n;

	ndx=0;
	for(n=0; n<30; n++){
		rdat[n]=gdat[n]=bdat[n]=0; //clear
	}
	rdat[ndx]=gdat[ndx]=bdat[ndx]=0xff; //set first
	c=0;
	while(c != 'q'){
		if(kbhit()){
			c=getchar();
		}
		vucom();
	}//while
}

//------------------------
void randcolorcom(void){
	//30 random color leds
	unsigned char n;

	for(n=0; n<30; n++){ //fill in 30 random colors
		rdat[n]=rand()%255;
		gdat[n]=rand()%255;
		bdat[n]=rand()%255;
	}
	send30rgbs();
	delnms(300);
}

//------------------------
void randcolorloop(void){
	//30 random colors
	unsigned char c;
	//unsigned char n;

	c=0;
	while(c != 'q'){
		if(kbhit()){
			c=getchar();
		}
		randcolorcom();
	}
}

//------------------------
void redwhiteblue(void){
	//10 red 10 white 10 blue
	unsigned char n,i;
	unsigned char r,g,b;

	for(n=0; n<10; n++){ //fill in 10 colors
		rdat[n]=0xff;
		gdat[n]=0x00;
		bdat[n]=0x00;
	}
	for(n=10; n<20; n++){ //fill in 10 colors
		rdat[n]=0xff;
		gdat[n]=0xff;
		bdat[n]=0xff;
	}
	for(n=20; n<30; n++){ //fill in 10 colors
		rdat[n]=0x00;
		gdat[n]=0x00;
		bdat[n]=0xff;
	}
	n=90;
	while(n--){
		send30rgbs();
		r=rdat[0]; //save 0
		g=gdat[0];
		b=bdat[0];
		for(i=0; i<30; i++){ //shift
			rdat[i]=rdat[i+1];
			gdat[i]=gdat[i+1];
			bdat[i]=bdat[i+1];
		}
		rdat[29]=r; //put 0 in 29
		gdat[29]=g;
		bdat[29]=b;
		delnms(50);
	}
}

//---------------------------
void demoloop(void){
	//ws2812 loop  30 leds grb
	unsigned char c,n;
	unsigned int i;

	initvars();
	res();
	c=0;

		
		alloff();
		send30leds();
		delnms(100);
		
		allon();
		send30leds();
		delnms(1000);
		
		allred();
		send30leds();
		delnms(1000);
		
		allgreen();
		send30leds();
		delnms(1000);
		
		allblue();
		send30leds();
		delnms(1000);

		i=90;
		while(i--){ //3 cycles
			knightridercom();
		}
		
		i=90;
		while(i--){ //3 cycles
			knightriderrandcom();
		}
		
		i=90;
		while(i--){ //3 cycles
			vucom();
		}
		
		i=90;
		while(i--){ //3 cycles
			randcolorcom();
		}
		
		i=90;
		while(i--){ //3 cycles
			redwhiteblue();
		}
		
	
}



int main(void)
{   
			port_init();
			initvars();
    while(1)
    {
        res();
	    allon();
        allred();
		
	    send30leds();
	    delnms(1000);
		//demoloop();   //right into demoloop
		
        //TODO:: Please write your application code 
    }
}

 

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

How do you expect us to give a reasonable reply? We have no idea of what your power source is, so, at best, you're going to get a guess. My guess is expecting 1.8 VA from a 1VA psu is hopeful at best.

You've got a logic analyser, so you make the timing measurements. The datasheet is pretty clear with the required timing.
Our job is to offer assistance, not do the work for you. Do you want to annoy us yet another time?

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

bianchi77 wrote:

Kartman wrote:
How many milliamps can each led ( or ws2812 draw)? Times by 30. Less than 500mA? Datasheet says 20mA per led. 30 x 3 x 20 I think you'll need a power supply

1.8 VA....

 

Where did you get VA from? The units is mA so 30 x 3 x 20 = 1800 mA or 1.8Amps. Nothing to do with volts.

 

Are you studying dressmaking with wearable electronics as a (very minimal) minor elective? Certainly seems like it.

 

Ross McKenzie ValuSoft Melbourne Australia

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

This is what I got from logic analyzer, it seems doing something but I can only see 1 from 30 LEDs is on with green color....

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

Do you expect we can magically check timing from that picture? that's your job. I wonder if anyone has written an analyser plugin for ws2812 protocol?

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

Those carefully timed delays probably only work in the imagecraft compiler. Try to declare the counting variable volatile. How come you got rid of the menu and the serial port stuff? And take the last semicolon out of the define. The last one comes from where you use the define.

 

 

Imagecraft compiler user

Last Edited: Sat. Oct 24, 2015 - 01:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I modify abit for

T0L T0H and T1L and T1H, now it works...

I check to logic analyzer and datasheet timing....

 

Thanks Bob...

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

Hi Bob,

 

Here's the result :

https://youtu.be/uAYyu3lXxjw

 

Is it possible to me for having :

rdat[ndx]=rand()%255;

 

to

rdat[ndx]=rand()%65536; or up to 16million ?

 

?

 

Because on datasheet, it says, it can be 24bits of colors ...

 

Thanks

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

Good Grief (Peanuts Charlie Brown). If you have 8 bits of black and white you have 255 levels of black and white. If you have 8 bits of RGB you have 256*256*256 colors of rgb which multiplies out to 16million. 65536 doesnt even hold 24 bits of rgb. If you want to show a fade with 16 million rgb colors from 0,0,0 to 255,255,255 you need to write 3 nested for loops on r and g and b from 0 to 255. Did you look at the c source to the program I posted? Frustrating.

 

Imagecraft compiler user