Not your average Arduino problem :s - Page 1
Forum section: electronics / general

author: cart
author_rank: Contributor
timestamp: February 26, 2013, 08:22:18 am
content: Hey Guys.I recently started working with Arduino to try pulse a motor driver which then drives a motor obviously -.- .But things really didnt work to well until I later learned that the maximum pulse that the Arduino can put out is just not sufficient at all andthat I needed a way faster pulse. analogWrite(1) - analogWrite(255) seems to be the same thing to the driver and the overhead of the arduino bootloader makes micros completely useless.So then I thought about a Microchip which gets driven by the arduino by some sort of pulse?Lest say the Arduino gives a PWM of 127 and a Microchip picks that up and sets the speeds accordingly?The Microchip would be the dedicated driver of the driver it seems.My question is...will this work and which chip will the be best for this application?I prefer 18F pics because I know how to program them (sort of) and they also come in smaller 28Pin packages.But if I do this..What should I know about pic programming to be able to set code this sort of program?My pseudo code from the top of my head for the Microchip.Check pulse from Arduino()if pulse is different then record the new pulse.Interrupt every 255 cylces to set up a flag and check if pulse have change ....Maybe Capture Compare?According to pulse work out some formula that will set the speed in MicroSeconds that a Pin is pulsed that will pulse the motor driver.Say on for 10uS and then off, Over and over again and can also be changed according to which speed we need.Do this your entire Microchip Life.

author: Mechatrommer
author_rank: Super Contributor
timestamp: February 26, 2013, 08:58:48 am
content: Quotego for AVR Studio IDE, write in real steel C or assembly, upload the hex with avrdude. if that is not enough for you, PIC is certainly not not not enough for you (if you do it correctly).

author: cart
author_rank: Contributor
timestamp: February 26, 2013, 09:39:56 am
content: Not enough?Well see the thing is I thought about leaving the arduino to do the LCD-drive and sensor-polling work and make the Microchip the soul driver of the motor.

author: Mechatrommer
author_rank: Super Contributor
timestamp: February 26, 2013, 09:50:13 am
content: Quote from: cart on February 26, 2013, 09:39:56 amoic. you didnt mention the lcd. sorry.

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 26, 2013, 10:02:02 am
content: If you ditch the Arduino library and just program the microcontroller directly you can get a much higher PWM frequency.So far as the LCD goes, you can find native drivers on the web. Just Google "avr hd44780 lcd library".

author: cart
author_rank: Contributor
timestamp: February 26, 2013, 11:00:52 am
content: Would probably need a programmer like the AVRtagicII or something to program without the Arduino Bootloader right?

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 26, 2013, 11:28:50 am
content: If you already have an Arduino then you can use ArduinoISP. It's one of the examples included with the environment. It will turn the Arduino into a AVR programmer.I would suggest getting a real programmer, however. Or, better yet, a programmer/debugger. For the money, Atmel's AVRISP mkII is pretty good. It is just a programmer, though. For a little more money you can get the Dragon, which will allow debugging.

author: psycho0815
author_rank: Regular Contributor
timestamp: February 26, 2013, 12:35:15 pm
content: You can change the frequency of the Arduino by setting a higher frequency and possibly a different PWM-Mode for the appropriate timer. Just be careful if you're using one of the OC0X pins. Changing the frequency on timer0 will screw with the delay() and millis() functions.If you feel that the Bootloader takes up too much space, you can tell the Arduino IDE to upload the sketch via a programmer, replacing the Bootloader. You will however need an isp-programmer for that.The Arduino-Environment is basically just a set of libraries on top of the avr-libc. No one forces you to use it. You can absolutely use the LCD-Library and still write your own code in plain c. I do that all the time.

author: Mechatrommer
author_rank: Super Contributor
timestamp: February 26, 2013, 01:41:12 pm
content: Quote from: cart on February 26, 2013, 11:00:52 amno need. you only need to do a little bit of work if you dont mind. the way Arduino IDE works is 1) compile your sketch (very slowly) and create a hex somewhere. 2) execute avrdude.exe with some parameters and link to the hex location in your HDD sent to it. 3) avrdude will upload the hex to the arduino board through the bootloader.... your job is to find that "parameters" or program "arguments" (old folks "command line" way of saying) in step 2. assuming you got the parm now, so you can manually upload any valid hex from avrdude in dos command line, direct usb connection, no need prorammer. now install AVR Studio, program to your heart content and build a hex, do as told, done.

author: cart
author_rank: Contributor
timestamp: February 26, 2013, 01:51:46 pm
content: Whoaaa! O.o!Sounds really really good!Im thinking of just leaving the Arduino as is and use another Atmega 328. I have a bunch of them so can just aswell?Program that in AVRStudio " Learn how to first ".This is my Arduino program is PERFECT and it works with Millis() and everything is awesome...Running its Clock at 16Mhz will destroy my Program and millis()Will a 328 be able to take UNO's PWM at 490Hz and do something productive with it?Maybe the whole interrupt to check PWM duty cycle change?Thanks guys, But ill have to learn Atmel now O.o

author: cart
author_rank: Contributor
timestamp: February 26, 2013, 01:53:46 pm
content: Let the tutorials begin i suppose.Please link me some useful stuff and also nudge me into a direction that I would find helpful on this particular subject, AnalgoRead , Catch Compares etc etc.Things Ill need for the job.Ohh BTW ! I have a have a SAM-ICE which I dont really know what to do with and a ATMEL AVRATJTAGICE MKII ...It has the AVR converter on with the six pin head.Think it didnt work to well last time I tried..probably why I didnt try again.Thanks allot guys REALLY appreciated!

author: psycho0815
author_rank: Regular Contributor
timestamp: February 26, 2013, 02:04:53 pm
content: Have a look athttp://www.avrfreaks.netthat should get you started. I can also recommend the atmega328's datasheet. IMHO it is very comprehensive and has example code in c and assembler for pretty much every function.If you want to upload your normal hex-files via the bootloader, have a look at the boards.txt file in Arduino's hardware folder. That schould contain the commandline for avrdude.That said, I still don't see why you would need two mcus for that.

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 26, 2013, 02:45:20 pm
content: In addition to the datasheet be sure to read the AVR libc documentation. It is installed when you install Atmel Studio.You should peruse the AVR application notes for information as well.App note 042will be one of the more important ones to read.You might want to pick up a USB to serial (TTL voltage level) cable too. This is one of the things you'll likely miss if you use the MCU standalone instead of on the Arduino board. I likethis onesince it does voltage translation. (Most of the other FTDI cables and boards don't do this.) You have to put a connector on it yourself, however. The AVR libc documentation explains how to set things up to use serial communication. It's just a couple of lines of code then you can useprintf()and whatnot.

author: Kremmen
author_rank: Super Contributor
timestamp: February 26, 2013, 03:22:19 pm
content: Quote from: cart on February 26, 2013, 01:53:46 pm+1 to everything the others already said. You of course knew that 8 bit Arduinos are powered by the same ATMega328 processor that you seem to have around. OK, the datasheet is your friend:http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf. You should take some time to study that, because that is the key to everything. Of course you need to know C or C++ as well (don't bother with assembly, your youth will be wasted with that). Atmel IDEs integrate the GCC that we have learned to love, in the form of avr-gcc and the associated runtime library adapted for Atmel processors, the avr-libc:http://www.nongnu.org/avr-libc/. This too you should understand (it comes with the Studio so you don't need to get ifrom anywhere, but do study the documentation.If you choose to go the dedicated AVR programming/debugging route (my recommendation as well), then by all means pick Atmel Studio 6 as your development environmenthttp://www.atmel.com/tools/ATMELSTUDIO.aspx. It has all you need, works right out of the box and is trivially easy to use. And, do learn the simulator. Once you do, many, many bugs will be strangled in their cradle before they ever make it to the flash image. Arduino does not have anything for a debugger, but eventually you will want one. If you got a working JTAGICE Mk II you are all set, that will work handily. Hold on to it. Using that one, you can do debugging directly from the IDE like a gentleman should. The correct way to connect it (you do have the adapter sockets and cables, right?) is explained in the Studio help. Just browse to the correct chapters.

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 26, 2013, 03:50:26 pm
content: Here are some code snippets from a couple of my projects that show how to use PWM on the AVRs. This will give you an idea of what you're in for. Notice how it's a bit lower level than the Arduino library but you'll have much more control. You'll understand what all those oddly named variables are once you read the datasheet.This is from an AVR ATmega324p project. PWM was used to sound a tone on a piezo buzzer...Code:void SetupTimer1(){// Timer1, which is a 16-bit timer, will operate in 'phase correct pwm' mode// (mode 11, specifically.) The timer will have the 8 MHz clock as its input// and will not be prescaled. Output compare pin OC1A will be controlled by// this timer. This pin is connected to one of the piezo buzzer's pins. (The// other piezo buzzer pin is connected directly to ground.) The buzzer can// be set to a specific frequency by setting this timer's OCR1A (aka TOP)// register.//// The buzzer's frequency and OCR1A (TOP) are calculated as follows://// f = 2,000,000 / OCR1A//// OCR1A = 2,000,000 / f//// It is important that PD5 (OC1A) is set low when the buzzer is off. This// prevents the buzzer from being driven with a DC voltage--which would be// the case if the pin were set high.// The timer will be setup so that it is explictly disabled...OCR1A = 0;TCCR1A = 0; // No clock source. Timer is stopped.TCCR1B = 0;TIMSK1 = 0; // No ISRs are used by this timer.PORTD &= (uint8_t)~_BV(PD5); // Make sure the OC1A pin is set low.}inline void SoundTone(uint16_t OCR1A_Value){OCR1A = OCR1A_Value;// COM1A1:0 = 01 (Toggle OC1A on compare match.)// COM1B1:0 = 00 (Normal port operation for OC1B, OC1B disconnected.)// WGM13:0 = 1011 (Waveform generation mode 11, PWM phase correct. TOP is OCR1A.)// CS12:0 = 001 (Clock source is CLKi/o / 1. No prescaling.)TCCR1A = (uint8_t)(_BV(COM1A0) | _BV(WGM11) | _BV(WGM10));TCCR1B = (uint8_t)(_BV(WGM13) | _BV(CS10));}inline void SilenceTone(){ // Currently, this is the same as DisableTimer1().TCCR1A &= (uint8_t)~(_BV(COM1A1) | _BV(COM1A0)); // Disconnect OC1A from the pin.TCCR1B &= (uint8_t)~(_BV(CS12) | _BV(CS11) | _BV(CS10)); // No clock source. Timer is stopped.PORTD &= (uint8_t)~_BV(PD5); // Make sure the OC1A pin is set low.}Here's another example. This time I made the code a little more modular and created a C++ PWM class. The methods are static (class methods) since the class is essentially a singleton and calling object methods have extra overhead. This is from an AVR ATmega324p project as well.File: PWM.h...Code:#ifndef _PWM_H_#define _PMW_H_#include <avr/io.h>class PWM{public:static void Init();static inline void SetCurrentDutyCycle(int8_t NewDutyCycle);static int8_t GetCurrentDutyCycle() { return OCR0B; }};inline void PWM::SetCurrentDutyCycle(int8_t NewDutyCycle){OCR0B = (NewDutyCycle > 100) ? 100 : ((NewDutyCycle < 0) ? 0 : NewDutyCycle);}#endif // __PWM_H_File PWM.cpp...Code:#include "PWM.h"void PWM::Init(){OCR0A = 100; // OCR0A is TOP.OCR0B = 100; // 100% (high) width.DDRB |= _BV(PB4); // Pin 4 of port b is OC0B. Set it as output.TCCR0A = _BV(COM0B1) | _BV(WGM00); // Phase correct PWM (mode 5, TOP is OCR0A.) Non-inverting mode.TCCR0B = _BV(WGM02) | _BV(CS01); // Prescale by 8.}