Shop OBEX P1 Docs P2 Docs Learn Events
Newbie modifying AVR Simon Game — Parallax Forums

Newbie modifying AVR Simon Game

jmadisonjmadison Posts: 7
edited 2010-12-09 17:29 in General Discussion
Hi everyone!

I am making a Christmas present that includes an AVR Simon game, and I'd like to modify the code to the game. BUT, I'm very new to this type of programming, and I could really use some help. I want to use the Simon game as a "combination lock" to open up the gift. Basically, I want to set it up so that the person receiving the gift has to repeat a sequence of 18 beeps before the micro controller turns a servo motor that will unlock the metal box housing the gift.

I built the AVR Simon game using the directions, but substituting the on-board switches for some long leads to some large switches off of the board. It works fine, is fun to play, and reminds me of my childhood in the 80's.

Next, I built a USBtinyISP programmer to allow me to reprogram it. I used avrdude from my linux box, and it recognizes the programmer, so I think that's ready to go.

I purchased a small servo motor to open and close the lock. It's a HEXTRONIIK HXT900 servo. I plan to hook up the motor to ground and to the PD4 pin.

Next, I went through the source code provided for the Simon game, and I tried to identify the changes that I would need to make so that after 18 correct repeats, it would power the servo. THIS is where I need help.

Here are my assumptions:

In avrsimon.h ....
add under //macros to set/clear a bit in register
#define _motoron(bit) (_cbi(LED_PORT, bit))

add
//motor pin
#define MOTOR_PIN PD4 // to use PD4 to turn the servo

change
#define EPROM_SIZE 128
to
#define EPROM_SIZE 18 // since the game "wins" when reaching EPROM_SIZE


Next, in main.c ......

add after //turnon all LED's in celebration
_motoron(MOTOR_PIN)

add in void hardware_init void
//set MOTOR_PIN to output
_sbi(LED_DDR, MOTOR_PIN);


Those are my assumptions... but I have a suspicion that the motor needs something more than that. I would really appreciate any help. I am very new to this type of programming, so I thank you for your patience.

Comments

  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2010-12-04 05:22
    I've changed my original post as I wasn't aware that Parallax has this product. I am a bit surprised that they are selling AVR boards, but it has been a year of changes.
  • jmadisonjmadison Posts: 7
    edited 2010-12-05 08:56
    Okay, so I've been reading on the Internet and learning a bit more. Apparently the servo isn't quite as simple as I had hoped. I was thinking that I could just send a voltage to it and it would turn. Now I understand that I need to send it a Pulse Width Modulated signal.

    So, what I'm thinking now is that I need to include a servo control function in my main.c or add it to my avrsimon.h file.

    Could anyone point me in the right direction so that I can set this up? Thank you very much.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2010-12-05 09:19
    Are you seeking a servo primer (briefing) or an AVR-definite interface example?
  • jmadisonjmadison Posts: 7
    edited 2010-12-05 10:40
    PJ Allen wrote: »
    Are you seeking a servo primer (briefing) or an AVR-definite interface example?

    Either one would be very helpful right now. I think what would be most helpful is an example of the C-code needed to make my servo move. I'm searching the internet a lot trying to learn more, but most examples I'm finding seem to be more detailed than I am ready for.

    Thanks for your interest.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2010-12-05 19:15
    OK
    There's good info in "Stampworks" .
    http://www.parallax.com/Portals/0/Downloads/docs/books/sw/Web-SW-v2.1.pdf

    What it boils down to is that you have to tick your servo regularly, to keep position, and the duration of that tick determines the position of the servo (or its speed and direction if it's the modified/continuous sort.)
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2010-12-05 22:42
    http://winavr.scienceprog.com/avr-gcc-tutorial/program-16-bit-avr-timer-with-winavr.html

    This may provide you with an AVR platform specific solution. R/C servos are driven by a rather slow and simple PWM loop.
  • jmadisonjmadison Posts: 7
    edited 2010-12-06 05:39
    Thank you both, PJ and Loopy, I'll read through those after work tonight.

    I've done a lot of reading to learn about the servo control, and I think I understand what I need to do, but I now need to figure out how to actually implement in the program I'm modifying.

    During game start up, I want to set the servo to zero degrees, (1ms pulse at 20ms frequency). Then, after the "game win" routine, I want it to move to 90 degrees (1.5 ms pulse at 20ms frequency). And I want to use the PD4 pin to be my 'control' pin, since that's not being used by the simon game.

    At this point, I don't know how to code the PWM signal. Hopefully after I read through those resources I'll have a better grip on it. Thank you.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2010-12-06 08:25
    I suspect that you would have to initialize the PWM in the 16 bit timer first in a 'closed position' and then go into the game. When the game is won, the PWM would adopt an 'open position' for a period of time, then return to closed.

    The basis for this approach is that I assume that the 16 bit timer will operate independently of the CPU in generating a PWM output. If you had to do this in a software timer, the programing would be more complex - a threaded program with an Interrupt Service Routine.

    With a bit of luck, I am hoping that you won't have to use an ISR. The main issue is that the installed AVR microcontroller has a hardware timer - some may not.
  • jmadisonjmadison Posts: 7
    edited 2010-12-06 18:00
    With a bit of luck, I am hoping that you won't have to use an ISR. The main issue is that the installed AVR microcontroller has a hardware timer - some may not.

    From the reading I've done so far, it seems that the AVR ATtiny2313 does have a hardware timer. I should be able to use it to generate the pulse.

    Off to read the resources you put up for me. Until later...
  • jmadisonjmadison Posts: 7
    edited 2010-12-08 17:31
    Well, I have read and read... and I'm getting a lot of good theory. But, so far I don't have enough to make a servo move in my project. I'll keep at it.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2010-12-09 04:47
    I suspect that there may be an easier PWM tutorial for AVRs somewhere on the web - that may help. Also, you don't have to use a 16 bit timer as 8 bit resolution is adequate for making an R/C rotate to merely two precise positions.

    So if the 8 bit timer looks easier, try that instead.

    Servos position clockwise/counter-clockwise on a pulse roughly from 0.5 to 1.5 mS (verify with your own hardware). That is the length of your pulse.

    The pulse needs to be repeated at a rate of about 50Hz or every 20mS in order to hold position.

    So, you may need to do some maths based on the clock rate of the microcontroller. Is is an external crystal or an internal oscillator? Then figure out how to get a 50Hz cycle free-running on the timer in the intialization, before you insert the pulse.

    As I mentioned before. I am hoping you can intialize the timer to one position; then play the game and have a win trigger the second position for a given period of time. So mostly you would need to study how to intialize a 50hz cycle and either a 0.5 or a 1.5mS pulse within that cycle.

    There is also some question of whether certain I/0 pins are designated for particular timers. If so, you may have trouble with the physical wiring.
  • jmadisonjmadison Posts: 7
    edited 2010-12-09 17:29
    I did find a lot of good information about AVR microcontrollers on www.avrfreaks.net.

    I have figured out that for my servo I want a 1ms pulse at 20ms frequency for the zero position, and 1.5ms pulse at 20ms frequency for the 90 degree. At least, I think that's right.

    There is an internal oscillator, so I don't need an external crystal. And, the pin I want to use for my PWM output -can- be used with the internal timer. So that's good.

    Now, my big challenge is to get the C-code written to do the servo move. I know where to insert that function in the 'game win' sequence in the main.c source, but I have to figure out how to actually write the code to initialize the pin as an output, and actually send the pulse to the pin.

    Pressing on...(and enjoying learning something new).
Sign In or Register to comment.