I suck at coding, please help. - Page 1
Forum section: electronics / beginners

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 10:43:14 am
content: So, you may have seen my post about building a boost converter, I am making a code for it, so I can get a PWM signal at a frequency that I want. Because analogRead() only does PWM at a certain frequency. So I want to have a part in the code where I enter in the Hz and a pin spews out the signal at the set frequency... (I'm using a 100k potentiometer to change the duty cycle) I got into it when I realised my coding skills are sadly incompetent. Here is my code, please explain to me how you pros would go about doing this. Thank you.const int sensorPin = A0;const int pwmPin = 3;int potvalPre;int potval;int stoptime1;int stoptime2;int freqHz;void setup(){pinMode(3, OUTPUT);Serial.begin(9600);}void loop(){potvalPre = analogRead(sensorPin);potval = potvalPre / 4;freqHz(2);//divide each stoptime by two, (freqHz) times./*Hz | Arduino delay() value total1 | 10002 | 5003 | 2504 | 125And so on...*///Serial.println(potval); (IGNORE THIS)//analogWrite(3, potval); (IGNORE THIS){digitalWrite(3, HIGH);delay(stoptime1);digitalWrite(3, LOW);delay(stoptime2);}}

author: madires
author_rank: Super Contributor
timestamp: September 10, 2017, 10:53:33 am
content: Some tips:1. tell people that you're writing code for an Arduino2. use the hardware PWM:https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 10:54:58 am
content: Quote from: madires on September 10, 2017, 10:53:33 amSorry.... but yes, I am writing code for Arduino.

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 10:57:53 am
content: Quote from: madires on September 10, 2017, 10:53:33 amI tried that, but I need a duty cycle that is variable... I can't do it with that can I? Also, are there any libraries that does this all for me?

author: Mechatrommer
author_rank: Super Contributor
timestamp: September 10, 2017, 11:07:15 am
content: what is freqHz()? and then its delared as int freqHzhow do you set stoptime1 and stoptime2?

author: madires
author_rank: Super Contributor
timestamp: September 10, 2017, 11:15:36 am
content: You can set the timer registers directly, no lib required. Use the prescaler to set the frequency and set the compare register for the duty cycle. In the main loop simply read the potentiometer and update the compare register. The hardware PWM keeps running all the time. And please spend some time to understand the PWM/timer modes.

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 11:19:40 am
content: Quote from: Mechatrommer on September 10, 2017, 11:07:15 amWell, I was going to make freqHz the value I have to change, to change the... frequency. The stoptime is:void setup(){pinMode(13, OUTPUT);}void loop(){digitalWrite(13, HIGH);delayMicroseconds(100); //<--- stoptime 1 (Approximately 10% duty cycle @ 1KHz)digitalWrite(13, LOW);delayMicroseconds(1000 - 100); //<--- stoptime 2}(code fromhttps://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM) I also tried this code, and the voltage is boosted to 60v, when I add a load (led with resistor) the voltage drops to 15v... so it kind of works? if I can get it to work with a variable duty cycle, then I'll try to start work on the feedback system.

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 11:23:49 am
content: Quote from: madires on September 10, 2017, 11:15:36 amok, let me look into that...

author: Mechatrommer
author_rank: Super Contributor
timestamp: September 10, 2017, 11:24:43 am
content: try this...Code:void setup() {pinMode(13, OUTPUT);}void loop() {potval = analogRead(sensorPin);if (potval > 1000) potval = 1000;digitalWrite(13, HIGH);delayMicroseconds(potval);digitalWrite(13, LOW);delayMicroseconds(1000 - potval);}another way is analogWrite() to set pwm output... ymmv...

author: Rerouter
author_rank: Super Contributor
timestamp: September 10, 2017, 11:33:11 am
content: To do this with the hardware, the function on arduino pin 3 (PD3) is OC2B, (Output compare B for timer / Counter 2Pretty much when its value matches the timers value, it changes. then the timer wraps around and begins counting, so if you have it set to match at a low value, it resets when the timer rolls over, reaches that low value and is on for a long time, or if you set it to match on a higher value, its on for a shorter amount of time, so PWM output with you only changing 1 value then forgetting about it until it next changes (hardware PWM)This is called the "Output Compare Unit" in the datasheet, ~ page 192 of the datasheet,http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdfAnd just down from that "Fast PWM Mode" on page 196, with the diagram on the top of 197 making clear what i am talking about.Now that your familiar with how hardware PWM works, jump to page 202 and it explains how the PWM prescaler works, this divides your 16MHz input signal in to a lower frequency clock to use for the timer peripheral, Timer 2 is an 8 bit timer, so your frequency is how long it takes to count to 255, (from 0)

author: skillz21
author_rank: Frequent Contributor
timestamp: September 10, 2017, 11:35:40 am
content: Quote from: Mechatrommer on September 10, 2017, 11:24:43 amSo, with the load, in the first maybe 30% of the Potentiometer's rotation, the voltage changes from 4.5v to 15v. Then for the rest of the potentiometer turn, the voltage hovers around 12 or 13v.... without a load it goas up to 60 something volts.

author: mrjiffy6
author_rank: Contributor
timestamp: September 10, 2017, 01:05:22 pm
content: I think the best answer to this post is pretty much what madires and Rerouter suggested: read the datasheet, learn about the arduino's internal peripherals and make it work!Or, you can still use the code proposed by Mechatrommer... The only caveat with this code snippet is the MCU will be 100% busy doing just that, leaving no MCU time at all for anything else.Hence you are obviously using arduino, I suggest you to take a look at the NewTone library, it was designed to generate specific tones to drive piezzoelectric buzzers, but all it does in fact is makes use of timers to generate PWM signals. It is far from being perfect, but at least you can learn how to implement a timer, timer overflow ISR, etc. That way, the MCU has plenty of time to execute other useful code!It might sound strange, but I think it's better to understand the internals first then really know how to codeIndeed, you will often discover a lot of internal things that can do what you want 10x easier and with 10x less of code than doing it all by yourself. Enjoy!

author: Fire Doger
author_rank: Regular Contributor
timestamp: September 10, 2017, 02:53:13 pm
content: The best way to do it is with Timer Compare Output in PFC mode (Phase and frequency correct) to avoid any crazy overshoot which may happen when changing the values. You can use Timer1 library which does it and have some examples on generating PWM.

author: Simon
author_rank: Unknown
timestamp: September 10, 2017, 07:15:13 pm
content: First understand the basics of "C", then study the micro's datasheet. I started on Arduino to get me the hang of C, but soon moved to direct coding of the chip as I made my way through the datasheet. I wrote a few (quite a few) "#define" statements into a header file for each periphery (ADC and two timer so far) so that I can say things like ADC_ON and it turns the ADC on, the code makes sense in english and i don't have to keep looking up register values in the datasheet, it's not quite as straightforward as the Arduino but a lot easier once you have got defines that make sense and can be reused, later you can concatenate them into specific combinations of defines to obtain a specific setup with just one instruction like the arduino does but i have not bothered yet.

author: krystian
author_rank: Contributor
timestamp: September 11, 2017, 12:21:05 pm
content: This behavior of your circuit that it changes voltage on its output only with small percent of potentiometer rotation is still an indication of too low frequency. You are oversaturating the coil. Think of a coil as a "capacitor of magnetic energy". But the difference is when you charge regular capacitor voltage on its terminals is slowly rising. But in case of a coil it's current which rises slowly. When you apply voltage to a coil, current flowing through it is slowly rising while inductor is storing energy in magnetic field around itself. When inductor is charged its just behaving like a piece of wire. You need to find maximum time of charge that is not making coil oversaturated. Simply shut down the mosfet until it charges completely. In your circuit you're charging it and after that your still holding current flow for a long time even if your coil can not store this much energy.Frequency you chose for your pwm is still too low.PM me, I will help you write your code step by step.

author: Mechatrommer
author_rank: Super Contributor
timestamp: September 11, 2017, 01:40:58 pm
content: Quote from: mrjiffy6 on September 10, 2017, 01:05:22 pmanalogWrite is write once function, i believe what it does is exactly like people said here about setting pwm registers OCR TCNT1 and all... once analogWrite is called, the pin output will forever producing the set pwm, no need 100% busy doing just that.

author: Buriedcode
author_rank: Super Contributor
timestamp: September 11, 2017, 04:56:01 pm
content: Quote from: skillz21 on September 10, 2017, 10:57:53 amThe acronym PWM stands for 'Pulse width modulation' which, by definition, is a varying duty cycle, with a constant period. Whilst many Arduino folks use it just to produce a square wave of varying period, ultimately, both period and duty (or rather, absolute on-time) can be changed. The AVR timer peripherals are more complicated than that on PIC micro's but ultimately more versatile. With Arduino libraries you can just use the built in routines, or use the registers directly, either way you set the frequency once and vary the duty.Also, using a micro for a boost converter might be OK as an exercise but there are dedicated devices that are much cheaper and 'better' for the task. Having software in the control loop adds significant delay meaning the output can easily oscillate. Some micro's will have built in comparators hooked to the timers to make it slightly easier to develop SMPS's. The limit on PWM frequency (62.5kHz " 8-bit for the Atmega328) means one requires rather large values for inductors and caps.Have you seen the many app notes form Atmel and Microchip on this?

author: Mechatrommer
author_rank: Super Contributor
timestamp: September 11, 2017, 05:16:49 pm
content: Quote from: Buriedcode on September 11, 2017, 04:56:01 pmi was about to suggest PID SW control loop yesterday, but since the OP want to manually set it by a trimpot, then i deleted the post... PID can be made stable, but will not be as fast as hardware feedback...

author: Simon
author_rank: Unknown
timestamp: September 11, 2017, 05:19:07 pm
content: I think the OP needs to read the ATMega328 datasheet section on the timer modules to get an understanding of what is happening under the hood.