W8-EMBEDDED PROGRAMMING¶
I decided to create a board that actually was useful for my final project, so I created the FUNDUINO, therefor I used the ATMEGA328P.
I had to research in the datasheet because I wanted to use the internal interruption of the clocks to prevent the loop to stop while doing something, in this case a conflict between the delays of the output and the need to read repeteadly the imput.
digitalWrite(Relay, RELAY_ON); // turn the relay on
delay(1000); // wait
digitalWrite(Relay, RELAY_OFF); // turn the relay off
delay(1000);
This is explained in deep in W11. The problem was solved modifying the PWM frequency.
Pulse width modulation, or pulse-duration modulation, is a method of reducing the average power delivered by an electrical signal, by effectively chopping it up into discrete parts. The average value of voltage fed to the load is controlled by turning the switch between supply and load on and off at a fast rate.
Is like a deemer to reduce light from a lamp by turning it on of so fast that the naked eye perceives a lower lumen value, in my case I use it to turn on and off a light at a certain rate in W11.
From the datasheet:¶
“Timer/Counter0 is a general purpose 8-bit Timer/Counter module, with two independent Output Compare Units, and with PWM support. It allows accurate program execution timing (event man- agement) and wave generation.”
“The double buffered Output Compare Registers (OCR0A and OCR0B) are compared with the Timer/Counter value at all times. The result of the compare can be used by the Waveform Generator to generate a PWM or variable frequency output on the Output Compare pins (OC0A and OC0B)” OC0B is my PWM output pin so:
int pin = 9;
The way is done is
In order to do that I can modify the timer interruption or use a library to control the PWM.
I tried to install it as a zip, it gave me an error of library names must start with a letter or number and no weird chars. I deleted the spaces and dashes, still didn’t work, it said Specified folder/zip file does not contain a valid library I unzipped and deleted all the example files, change the name to PWM.h and then rezipped it, Now it works (Previously I had copied the unzipped folder in libraries directly and didn’t work for the same reason).
// Control the relay with pwm to avoid the delaying of the loop
#include <PWM.h>
int pin = 9;
int32_t frequency = 1;
void setup() {
// put your setup code here, to run once:
InitTimersSafe();
SetPinFrequencySafe(pin,frequency);
}
void loop() {
// put your main code here, to run repeatedly:
pwmWrite(pin, 127);
}
I program it as an ATmega328 with a 16MHz clock with the arduino program, through a FTDI cable, setting as a programmer ARDUINOISP.
I have to remember that as we deal with frequencies, to get the former delay form 1000ms now I have to put 0.5Hz because it goes up and down in one cycle. Sadly this library sets frequency as an integer of 32 bits, I might try to change the library to use a float, but as this is not really important for the project, only for testing the relay, I wont kill myself with t, in any case I can create an internal interrupt within a timer
In any case if I cannot do less than 1Hz, it means I can’t have one second 5V and 1 second 0V as this would require to program the PWM frequency to 0.5Hz.
“Clear Timer on Compare Match (CTC) Mode In Clear Timer on Compare or CTC mode (WGM02:0 = 2), the OCR0A Register is used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when the counter value (TCNT0) matches the OCR0A. The OCR0A defines the top value for the counter, hence also its resolution. This mode allows greater control of the compare match output frequency. It also simplifies the operation of counting external events.”
I believe I can’t set 0.5Hz due to the resolution of the timer, but looking at the code, the problem seems to be that the variable that sets the frequency is an integer not a float, so I would have to go deeper in the code and set it as float and then change the OCR0A so it counts in ms.
OTHER LANGUAGES¶
I’ve worked extensively in assembler in college, so I’m gonna try C.
I got this ebook which is very interesting if you wanna optimise memory.
I try this program to make a led blink,
#define F_CPU 4000000UL
#include <avr/io.h>
#include <avr/delay.h>
#include <util/delay.h>
int main (void)
{
DDRB = 0xFF;//Set PORTB to outputs
while(1) {
//this turns LED at C0 on/off
PORTB |=(1<<6);//B13 HIGH
_delay_ms(1000); //PAUSE 1second
PORTB &= ~(1 << 6);// B13 LOW
_delay_ms(1000);//PAUSE 1 second
}
}
PORTB |=(1<<6); What is happening here is that every pin on PORTB is being compared to the state(s) proposed by the equation in the parentheses. (The shift left command (<<))
The syntax is:
PORTx |=(the value<<number positions).
This means that in port B and the value = 1 and the number positions shifted is 6 meaning pin13 on PORTB will go high. If the number positions shifted is (1<<3), the bit is shifted three times, followed by zeros