Controlling WS2812B LED strip with ATmega324PB Xplained PRO

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

1. Tell us WHAT you are trying to do. That is, please tell us (a) what you have done, (b) what you expected to happen, and (c) why you think that (a) should result in (b)!!

(a): I am trying to address 10 LEDs in a WS2812B LED strip to be a series of colors. And just leave them on. Once I get this working, I can continue to the main large scale grid project I am working on. I am basing my code off of a code for Arduino called Bitbang_whitish (found at http://www.instructables.com/id/... also attached below, original and modified). In the arduino IDE, I can use this code to generate all LEDs white, modifiy it to change their color, and add variables and if-statements to use magnetic reed switches to control when the lights turn on. The problem is I need to use the ATmega324pb as part of a course requirement, not an Arduino. I started with the arduino as a proof of concept.

(b): I worked with partially with a teacher's assistant to transfer the code from Arduino into Atmel Studio 7. We have modified the code significantly to work in c++. I unfortunately feel the the inline assembly portion of the arduino code might not be ported over properly, that is my first suspicion as to why it does not work and I am unsure on how to solve it. The code compiles, and according to oscilloscope readings there appears to be high and low data being sent out of the data pin (PORTB0), but it is much more infrequent than it should be. the LEDs remain off.

 

2. Provide us with CODE. Don't hand copy the code, but copy and paste, so that errors are preserved. Use the code buttons at the beginning and end of the code listing (works best if you click the code button, paste the code, then click the "end-code" button at the end). This will make it much easier to read and others will be more likely to look at it. If the code is big (maybe more than a 50-100 lines or so), reduce the code to a small version that demonstrates the same problem. Make sure that the code you provide COMPILES! PLEASE, tell us what compiler or assembler and what version you are using.

I have attached my Atmel studio project in a .zip file. I commented out many of the statements in the main and left only enough to turn the LEDs on (setColorRGB calls for each light). 

 

3. Tell us how the FUSES are set and what you use as a clock source.

I am using the external crystal oscillator on the ATmega324PB Xplained PRO dev board. I have attached a screenshot of the fuses menu (screenshot says simulator as I do not currently have the xplained connected, but the information is the same settings).

 

4. Tell us what PROCESSOR you are using.

I am unsure what you mean.

 

5. Tell us if you have tried to SIMULATE the operation of the code. If you did, tell us what you found.

Well, I was able to get a simple code to turn the LEDs on when a switch was pressed. with some LEDs I changed to color of it when the switch was closed. It works in Arduino.

 

6. Provide us with some DETAILED OBSERVATIONS about what it is or is not doing. This should relate to 1(b)(, above. "Doesn't work" covers a lot of territory! Is your LED off when it should be flashing, is your motor turning or not. Tell us what test equipment (volt meter, oscilloscope, etc) are available to you, what measurements you have actually made, and what the measurement results were.

I think I may have answered this earlier, but ask for more if needed.

 

7. If you have some suspicions about why it does not work, tell us what the evidence is for your diagnosis.

The inline assembly text is red, which I am unsure if that is normal when using asm in a main.cpp. I am unfamiliar with the use of assembly, but because the timing needs to be precise (0.8us high and 0.45us low for a "1" and 0.4us and 0.8us low for a "0" bit) for the WS2812B strips, assembly is used as well as cli() to clear interrupts.

 

8. If you think that there is a hardware problem, provide a circuit diagram. Or, tell us what development board you are using and HOW you connect to it.

I do not believe there is a hardware problem as the LEDs can be addressed on an arduino. bright and colorful!

 

10. PLEASE do NOT use shorthand "texting" language. Spell words out as real words and use a spellchecker. You will get faster and better help if you do. Also, "The Curmudgeons" will not make rude remarks about your post.

Well, I checked for errors and tried to be as clear as possible. Please tell me if anything is unclear and I will explain to the best of my ability.

 

11. Words like "urgent", "ASAP", "I need it very quickly" and so forth do NOT get you good answers. All capitals, many question marks or exclamation marks don't help either. Asking the same question several times (duplicate post) will make a very bad impression.

I know it might be hard to see what i'm trying to do so again, ask away if you need anything from me.

Attachment(s): 

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

4. Tell us what PROCESSOR you are using.

I am unsure what you mean.

Aren't you using the mega324PB?  This does not refer to the PC.

 

Build up your program slowly, just start out by sending a fixed pattern to the strip (no bit reversal/flipping), to see if that runs the strip at all.  No reading switches or anything else, just power up & spit the bits to generate green, or some color. Then add the other bells and whistles.

Also, ensure you are using the ext xtal osc fuse (if that is what you want)

When in the dark remember-the future looks brighter than ever.

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

All that my Atmel Studio code is doing is setting colors to 10 LEDs in a row. The Atmel Studio project does not try to use switches (yet). All it is supposed to do is set colors to the strip. Using switches was referring to the Arduino code. 

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

As far as I can see, you never set your data pin to be an output. You even mention it yourself in the code:

 

//DDRB = 0x01;
//PORTB = 0x06;
/*
Why are these two lines (above) here is the pin is defined higher up? 
i'm not sure if we need these, but we probably do and i'm just missing something. commenting them out eliminated
6 errors, leaving only 3: recipe failed, and two relating to "micros"
*/

You need to have (at least) the DDRB = 0x01 line to make PORTB bit 0 an output.

But you need to put it in the beginning of your main function, instead of where it is now.

 

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

uncommenting the "DDRB = 0x01" came up with the following error list

Attachment(s): 

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

I then decided to add "volatile uint8_t" to each of the variables in the "render()" function, hoping that would declare them all. Is this not the case? am I not declaring them properly? what is it I am doing wrong. The error list still remains the same, calling them undeclared.

Attachment(s): 

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

As you already know timing for WS2812 is relatively tight at around 800kbit/s.

You have observed irregularities in the timing and suspect teh translation of inline asm during the port of C -> C++.

Is it individual bits that are off, or are you experiencing intermittent delays in the data bits?

Bitbanging at these data rates is only possible if interrupts are disabled during the duration of the bitbanging (or hardware SPI, etc).

You have commented out some of the sei() and cli() code, which is for enabiling and disabling interrupts. Not good for bitbanging at 800kHz.

The ASM code is also timing sensitive and dependent on a specific F_CPU.

That code will not work without modification if any another crystal frequency is used.

 

Addition to post #4:

AVR IO registers are made out of 3 bytes ( "x" = A, B, C, D, depending on the port number):

DDRx    = Data Direction register (Are the pins Inputs or Outputs?)

PORTx  = Data register used for writing to outputs.

PINx     = Data register for reading the Inputs.

For more info on this Check out the I/O port section of the datasheet.

 

Addition to post #5:

You seem to have unmatched parentheses in line 58, or just before that.

It may also be a missing semicolon.

All following errors are likely the cause of the compiler getting confused.

Somewhat later...

I had a breef look at your main.cpp. It looks like there is something going wrong in the macro expansion of the macro's "DDRB" or "PORTB".

 

Addition to post #6:

Adding and / or changing other things before this (probably a simple typo) is resolved will not get you closer to a clean compile.

I do not have AS7 and can not help you with that.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

Last Edited: Tue. Apr 24, 2018 - 10:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the help. I realized that I had the "DDRB = 0x01" before the main, so I moved it in, then added a semicolon afterwards. After that, my only errors were "undeclared variable 'x'" in the "render" function. After looking at it, I changed all of the commas after each volatile uint8_t to semicolons, then put a '*' before the variable rgb_arr. That solved all of the errors and now my oscilloscope readings are all within range and sending clear 1s and 0s. Thanks for the assistance!

Attachment(s): 

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

Code must indeed be within functions. How silly of me that I did not spot that earlier.

 

I was also a bit confused by your render() function. It's body seemed to be defined inside of main().

On closer inspection however I saw that only the indentation was messed up a bit.

This can easily be corrected with a program such as "indent" or "astyle", and your IDE may also have built-in functions to re-format code.

 

You may also mark this thread as "solved". AwNeil likes that.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

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

I do not know what frequency the crystal on the Xplained board younre using is at so forgive me if I am wrong here, but....

As noted the timing atb800khz is pretty tight, the Adafruit arduino library is mostly ASM code for this reason.

My question is why not simply integrate the Adafruit library into your project? It works and is very straight forward.

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Apr 25, 2018 - 02:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your fuse screen shows that the AVR is running at 8MHz using the internal RC clock instead of the 16MHz crystal.   This is making it impossible for the assembler code to precisely turn off and on the WS2812 (NeoPixel) data line.  These LEDs need tightly-coded precision when using AVRs.  The WS2812 NeoPixels will work at 8MHz; but the code needs different assembler routines for that speed.

 

Use the code that Adafruit provides for Neopixels.  It works well and there is a section that has assembler routines for 8MHz AVRs, as well as 16 MHz ones.

 

I don't use Atmel studio often because it takes 120+ seconds to load on my laptop. I remember being able to load and compile an Arduino program sketch into it (Atmel St Ver.8)  and have it compile.

Arduino is already in C++.  You shouldn't need to do anything to the code except handle Arduino-specific AVR-peripheral commands like analogWrite(). 

 

It doesn't hurt to learn how to transfer code back and forth between Atmel Studio and Arduino for the Mega328P and PB - class of devices.  Although in the real world, Arduino will probably be around a lot longer than Atmel Studio because it's a world standard that is learned by everyone,  it's easier to use than Studio, and it can do anything that Studio can except run expensive debug interfaces or the flaky AVR Dragon.  Arduino only works (realistically) with the Mega328P and the Mega2560, while Studio handles all the hundreds of AVR device types.

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

jgmdesign wrote:
I do not know what frequency the crystal on the Xplained board younre using is

Previous thread said it's 16MHz:

https://www.avrfreaks.net/forum/atmega324pb-external-xtal-16mhz

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:
You may also mark this thread as "solved". AwNeil likes that.

For instructions, see Tip #5

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
transfer code back and forth between Atmel Studio and Arduino

Atmel Studio can import an Arduino "sketch" - but I wasn't aware of any facility to export it back to Arduino ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...