hexagon5un / AVR-Programming

Code examples for the book "Make: AVR Programming"
http://littlehacks.org/AVR-Programming
MIT License
725 stars 340 forks source link

Chapter 2 - BlinkLED with ATMega 328p #24

Open lambdamikel opened 7 years ago

lambdamikel commented 7 years ago

Hello, congratualations to this great book! However, I had a very hard time getting BlinkLED from Chapter 2 to work... Figure 2-8 just wouldn't work with the "Atmega328p-pu Chip w/ Arduino UNO Bootloader" that I had purchased from Amazon. I knew that everything was fine with them, as they worked well in my Arduino Uno R3 board. I had the exact same setup as in Figure 2-8, and the Pocket AVR Programmer / usbTiny. However, I always got the "avrdude: initialization failed, rc=-1" error message. The programmer was working as I could see from its blinking lights upon transmission, but it couldn't talk to the Atmega.

On page 39, you are discussing possible causes for this "rc=-1" error - however, it is not mentioned that certain Atmega 328p's (such as mine) are configured such that they need an 8 Mhz or 16 Mhz quartz, as shown in https://www.arduino.cc/en/uploads/Tutorial/BreadboardAVR.png. For me, this was the only way I could overcome this issue. Added the 8 Mhz (16 Mhz) quartz and the 2 20pf capicators - problem solved. It took me 8 hours to figure that out, though :-(

It would be extremely helpful to at least mention this possibility in the book and put a pointer there, otherwise newbies will be extremely frustrated. Maybe for the next edition of the book?

Thanks for the great book otherwise, Michael

defconx commented 7 years ago

@lambdamikel Michael. I experienced a similar issue as you and I was able to resolve it. I pulled my 328p-pu chip out of a working Arduino board and I program it with using my Evil Mad Scientist shield, but I couldn't get it to run independently on a board without a crystal. After doing some research this morning, I discovered my chip was setup to use an external timer (crystal) vs internal. Using the internal clock is default from the factory according the the Atmel documentation. I am assuming the fuses were different (from factory) because I pulled it from an Arduino Uno that had an external clock on the Arduino board. I ran the following command appended to my regular avrdude command to set the fuses to enable the internal clock: -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m making my full command: avrdude -v -p atmega328p -c avrisp -P /dev/cu.usbmodem1411 -b 19200 -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m You can use the calculator here: http://www.engbedded.com/fusecalc Reference: Section 9.6 Calibrated Internal RC Oscillator (page 34) of the Atmel ATmega 328 Datasheet (full version) I hope this helps as I was in the same situation you are and was able to resolve it. Good luck & good programming!

lambdamikel commented 7 years ago

Thanks for your reply. I know (and was able) to resolve this of course, my comment is more on improving the readbility of the book. The point is really that a book for beginners should at least discuss these options and present pointers as to how to resolve it, in the first or second chapter. Because otherwise, the beginner will get stuck in Chapter 2 and move on to a different book :-) A beginner will not read the datasheet.

hexagon5un commented 7 years ago

You already found the "set fuses" solution to the problem, so that's great. The other possibility is to buy a 16 MHz (or whatever) crystal and just plug it in where it goes: PB6,7 on the AVR. If you did that, you'd have to change the CPU speed in the Makefile (see below).

But the bigger question is what's the easiest/cheapeast way to get the hardware. A few years ago, it was "just order a bare chip", but now there's an entire ecosystem of people selling Arduino-compatibile chips with the fuses already burnt like you found, and there are pre-built "Arduino" clones that are only a tiny bit more expensive than buying the straight chips.

If I were re-doing the book (maybe a 3rd edition?) I would change the hardware platform. Since the time the book was written, cheap "Arduino" mini clones have become the cheapest/easiest way to get started with AVRs.

There are only two changes you'd need to make. One is hooking up the SPI wires correctly, and the other is making sure the delay and baud-rate functions know what speed your processor is running at.

Some of the clones have a 6-pin ISP header broken out on the thin side of the board opposite the serial adapter. Connect pins and plug it into the 6-pin header on your programmer. Done.

Otherwise, you'll have to hook them up as follows: RESET, VCC, GND are obvious MISO: D11 MOSI: D12 SCK: D13

That'll get you programming.

Now, the chip is clocked at 16 MHz instead of 1 or 8. You'll need to edit F_CPU in the Makefile accordingly to read 16000000UL.

And that's it. The rest should work with the code in the book (untested!), and you get a convenient serial port connection to boot. Let me know if you try this out.

nblyumberg commented 5 years ago

Hi Elliott,

Feedback from someone who's working their way through the book, and seeing these comments after running into the same problem as others:

A few comments and to echo some of the feedback from others:

  1. I actually prefer that you don't switch the book to a different hardware platform and stick to the bare chip approach your book uses, i've skimmed a few of the Arduino books previously and they obfuscate a lot of the details that are interesting and important. As I haven't gotten through the rest of the book, I can't really comment on the rest of the content.

  2. The comments about the rc=-1 error are spot on, the book should include a note about the fuses, a few possible breadboard scenarios to overcome this, instructions on how to set the fuses with your programmer.

  3. It would also be beneficial to include a prebuilt hex file that could be flashed once you overcome the external oscillator problem so you are starting in a "known good state". I've built the chapter 2 circuit about 5 times already and only got to blink the LED once. I can program the chip but my pin doesn't seem to do anything beyond that.

Thank you for the book, I am hoping to get through it to get a better understanding of underlying technologies for all things Arduino.