(Deutsche Version) Today, I want to refer to a useful program:
TinyCAD
With this program, you can draw circuits on a very easy level and export them as an image. You do not need to create an account or anything like that. The program is very simple and does exactly what you want so you do not need to take 100 tutorials to being able to draw a simple circuit.
A collection of my projects in the areas of physics, electronics and information science.
AdSense
Monday, 17 February 2014
Control LED strip with ATmega / Arduino
(Deutsche Version) LED strips have been gaining more and more popularity within the last few years. There are even LED strips for less than 20 euro from china. Usually, an LED strip consists of a control unit, a power supply and a remote. For most people, this is sufficient. Anyone who wants to have more (e.g. run through sequences) has to put in a little effort.
Let's primarily face the structure of the strip. There are four connections, one of them is for the + 12 V power supply, the other three connections are for the individual colours. The strip is working like this: If you apply + 12 V and then connect ground to one of the colour connections, this colour is shining. The brightness is now controlled vie PWM. To fully control the LED strip you need:
To control a single color, you have to execute:
This command will set the transistor which is connected to pin 8 to 50% (255 is the maximum), so the connected colour has 50% brightness. You can only use PWM channels for this (in the data sheet usually referred as OCR).
To achieve any color, you have to mix the colors. therefore, you have to choose a colour in the RGB space, e.g. orange: this colour is R: 255, G:255, B:0. Now you have to program this into the microcontroller:
It could occur that different colours are seen at different brightness, you should test this and then set the maximum limit e.g. for green to 127 (green appears very bright for the human eye, therefore the green colour could be too bright.
Let's primarily face the structure of the strip. There are four connections, one of them is for the + 12 V power supply, the other three connections are for the individual colours. The strip is working like this: If you apply + 12 V and then connect ground to one of the colour connections, this colour is shining. The brightness is now controlled vie PWM. To fully control the LED strip you need:
- A microcontroller (ATmega / Arduino)
- 3 bipolar transistors (NPN) which can handle enough current!
To control a single color, you have to execute:
analogWrite(8, 127);
This command will set the transistor which is connected to pin 8 to 50% (255 is the maximum), so the connected colour has 50% brightness. You can only use PWM channels for this (in the data sheet usually referred as OCR).
To achieve any color, you have to mix the colors. therefore, you have to choose a colour in the RGB space, e.g. orange: this colour is R: 255, G:255, B:0. Now you have to program this into the microcontroller:
analogWrite(RED_PIN, 255);
analogWrite(GREEN_PIN, 255);
analogWrite(BLUE_PIN, 0);
It could occur that different colours are seen at different brightness, you should test this and then set the maximum limit e.g. for green to 127 (green appears very bright for the human eye, therefore the green colour could be too bright.
Sunday, 16 February 2014
"Home Automation" with Arduino and 433 MHz - The complete remote control
(Deutsche Version) I finally merged the control for my shutters and the power outlet into one program and built a small remote control.
Hardware
There is not much to say about the hardware:
It's an Attiny44A, a pullup resistor for the RESET-pin, three buttons (up, down, stopp), a button cell holder and the 433Mhz transmitter. Each button is connected toan input of the Attiny. If the button is triggered, the input is pulled to ground.
Software
The functions for controlling the shutters and the power outlet have been explained in my other posts (unfortunately at the moment these posts are only available in german), so I'm not going to explain the following source code in detail.
The remote control is powered by a CR2032 button cell, so the amount of available energy is limited. Since the control isn't doing anything 99.999% of the time, the Attiny enters sleep mode using the powerdown() function. It sleeps until a button is triggered (Pin-Change-Interrupt). To save as much energy as possible, ADC and AC are switched off.
Hardware
There is not much to say about the hardware:
It's an Attiny44A, a pullup resistor for the RESET-pin, three buttons (up, down, stopp), a button cell holder and the 433Mhz transmitter. Each button is connected toan input of the Attiny. If the button is triggered, the input is pulled to ground.
Software
The functions for controlling the shutters and the power outlet have been explained in my other posts (unfortunately at the moment these posts are only available in german), so I'm not going to explain the following source code in detail.
#include <RCSwitch.h> #include <avr/sleep.h> #include <avr/wdt.h> RCSwitch mySwitch = RCSwitch(); unsigned char buttonDown = 10; unsigned char buttonStopp = 9; unsigned char buttonUp = 7; unsigned char buttonPressed = 0; char stopRequest = 0; void setup() { //disable interrupts cli(); //initialize pins pinMode(buttonDown, INPUT_PULLUP); pinMode(buttonStopp, INPUT_PULLUP); pinMode(buttonUp, INPUT_PULLUP); //initialize transmitter and switch off power outlet mySwitch.enableTransmit(0); //transmitter is connected to pin 0 mySwitch.setProtocol(1); mySwitch.switchOff("11011", "10000"); //save energy! ADCSRA &= ~(1<<ADEN); //disable ADC ACSR = (1<<ACD); //disable Analog Comparator //initialize Pin-Change-Interrupt PCMSK1 |= (1<<PCINT8); //Pin-Change-Interrupt at pin 2 (Arduino Pin 10) PCMSK1 |= (1<<PCINT9); //Pin-Change-Interrupt at pin 3 (Arduino Pin 9) PCMSK0 |= (1<<PCINT7); //Pin-Change-Interrupt at pin 6 (Arduino Pin 7) //prepare Power-Down-Mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); //enable interrupts sei(); } void loop() { sendCommand(); powerDown(); } void sendCommand() { if (buttonPressed == buttonDown) { mySwitch.switchOn("11011", "10000"); delay(750); sendCommandDown(); powerDown(25); mySwitch.switchOff("11011", "10000"); buttonPressed = 0; } else if (buttonPressed == buttonUp) { mySwitch.switchOn("11011", "10000"); delay(750); sendCommandUp(); powerDown(25); mySwitch.switchOff("11011", "10000"); buttonPressed = 0; } } //command shutters up void sendCommandUp() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100F0F0F"); mySwitch.sendQuadState("0F0F0100QQ0F100F0F1Q"); mySwitch.setProtocol(1); } //command shutters stopp void sendCommandStopp() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100FFFFF"); mySwitch.setProtocol(1); } //command shutters down void sendCommandDown() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100F0101"); mySwitch.sendQuadState("0F0F0100QQ0F100F0110"); mySwitch.setProtocol(1); } //let Attiny wait for time secinds void powerDown(char time) { GIMSK |= (1<<PCIE1); //enable Pin-Change-Interrupt GIMSK |= (1<<PCIE0); stopRequest = 0; for (char i = 1; i<= time*1000; i++) { if (stopRequest == 0) { delay(1); } } GIMSK &= ~(1<<PCIE1); // disable Pin-Change-Interrupt GIMSK &= ~(1<<PCIE0); } //set Attiny to Powerdown-Mode until Pin-Change-Interrupt void powerDown() { GIMSK |= (1<<PCIE1); //enable Pin-Change-Interrupt GIMSK |= (1<<PCIE0); sleep_mode(); //go to sleep //software will continue here after leaving sleep mode GIMSK &= ~(1<<PCIE1); //disable Pin-Change-Interrupt GIMSK &= ~(1<<PCIE0); } void checkButton() { if (digitalRead(buttonDown) == LOW) { buttonPressed = buttonDown; } else if (digitalRead(buttonStopp) == LOW) { stopRequest = 1; mySwitch.switchOff("11011", "10000"); } else if (digitalRead(buttonUp) == LOW) { buttonPressed = buttonUp; } } //ISR for PCINT1 and PCINT0 (Pin-Change-Interrupts) ISR(PCINT1_vect) { checkButton(); } ISR(PCINT0_vect) { checkButton(); }
The remote control is powered by a CR2032 button cell, so the amount of available energy is limited. Since the control isn't doing anything 99.999% of the time, the Attiny enters sleep mode using the powerdown() function. It sleeps until a button is triggered (Pin-Change-Interrupt). To save as much energy as possible, ADC and AC are switched off.
Sunday, 27 October 2013
Arduino-Code on the ATmega 1284P
(Deutsche Version) Running Arduino code on an ATmega 1284P is pretty simple. You only have to execute some small steps. At first, you have to download the following archive:
https://github.com/maniacbug/mighty-1284p/zipball/master
The content has to be extracted to C:\Program Files (x86)\Arduino\hardware\mighty-1284p (respectively the location where you installed the development environment). Afterwards, the development environment has to be restarted. Now, the 1284 can already be selected. I use the Original Mighty 1284p 16MHz. The pin mapping is different, see below (The number in the Parentheses is relevant for the Arduino):
https://github.com/maniacbug/mighty-1284p/zipball/master
The content has to be extracted to C:\Program Files (x86)\Arduino\hardware\mighty-1284p (respectively the location where you installed the development environment). Afterwards, the development environment has to be restarted. Now, the 1284 can already be selected. I use the Original Mighty 1284p 16MHz. The pin mapping is different, see below (The number in the Parentheses is relevant for the Arduino):
+---\/---+
(D 0) PB0 1| |40 PA0 (AI 0 / D24)
(D 1) PB1 2| |39 PA1 (AI 1 / D25)
INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D26)
PWM (D 3) PB3 4| |37 PA3 (AI 3 / D27)
PWM/SS (D 4) PB4 5| |36 PA4 (AI 4 / D28)
MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D29)
PWM/MISO (D 6) PB6 7| |34 PA6 (AI 6 / D30)
PWM/SCK (D 7) PB7 8| |33 PA7 (AI 7 / D31)
RST 9| |32 AREF
VCC 10| |31 GND
GND 11| |30 AVCC
XTAL2 12| |29 PC7 (D 23)
XTAL1 13| |28 PC6 (D 22)
RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI
TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO
RX1/INT0 (D 10) PD2 16| |25 PC3 (D 19) TMS
TX1/INT1 (D 11) PD3 17| |24 PC2 (D 18) TCK
PWM (D 12) PD4 18| |23 PC1 (D 17) SDA
PWM (D 13) PD5 19| |22 PC0 (D 16) SCL
PWM (D 14) PD6 20| |21 PD7 (D 15) PWM
+--------+
Thursday, 24 October 2013
Control RGB LED with ATmega16A
(Deutsche Version) RGB LEDs are pretty interesting (e.g. if they are in an LED strip). Today, I want to explain how to control an RGB LED with an ATmega16A. At first a short introduction to the RGB LED: I use this LED from Tayda Electronics. This LED consists of three different LEDs which are all in the same body. Therefore, there are 3 pins for the different LEDs and a common cathode (-). If you apply a PWM signal to these 3 pins, you can control the color of the LED. I use the ATmega16A because the ATmega8 only has 2 PWM channels, this is not enough for 3 pins. This should cover the basics for an RGB LED, here is the code which runs through the whole colour space:
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
int main(void)
{
DDRA = 0xFF;//Output
DDRD = 0xFF;
ICR1 = 256;
TCCR2 = (1<<WGM20) | (1<<COM21) | (1<<CS20); // PWM, phase correct, 8 bit.
TCCR1A = (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1); // PWM, phase correct, 8 bit.
TCCR1B = (1<<CS10);// | (1<<CS10); // Prescaler 64 = Enable counter, sets the frequency
double rCounter = 255;
double rMax=255;
double bCounter = 255;
double bMax = 180;
double gCounter = 0;
double gMax = 70;
int stages = 0;
while(1)
{
switch (stages)
{
case 0:
bCounter --;
if (bCounter <= 0)
{
stages = 1;
}
break;
case 1:
gCounter ++;
if (gCounter >= 255)
{
stages = 2;
}
break;
case 2:
rCounter --;
if (rCounter <= 0)
{
stages = 3;
}
break;
case 3:
bCounter ++;
if (bCounter >= 255)
{
stages = 4;
}
break;
case 4:
gCounter --;
if (gCounter <= 0)
{
stages = 5;
}
break;
case 5:
rCounter ++;
if (rCounter >= 255)
{
stages = 0;
}
break;
}
OCR1B = (int)(bCounter*bMax*bCounter/255/255);
OCR1A = (int)(gCounter*gMax*gCounter/255/255);
OCR2 = (int)(rCounter*rMax*rCounter/255/255);
_delay_ms(5);
}
}
Tuesday, 8 October 2013
C# - List all files in folder and sub folders
(Deutsche Version) Reading all files in a folder is pretty simple (see also C# Tipps and Tricks). If you want to do this recursively, the solution is also simple. The code I therefore use is the following:
To filter this result, you can add a .Where at the end, the following code will only list audio files:
var allfiles = System.IO.Directory.GetFiles( @"C:\YourFolder", "*.*", System.IO.SearchOption.AllDirectories);foreach (string file in allfiles)
{}
To filter this result, you can add a .Where at the end, the following code will only list audio files:
var allfiles = System.IO.Directory.GetFiles( @"C:\YourFolder", "*.*", System.IO.SearchOption.AllDirectories).Where( s => s.EndsWith(".mp3") || s.EndsWith(".wav") || s.EndsWith(".wma"));
foreach (string file in allfiles)
{}
Labels:
C#
Monday, 7 October 2013
LCD Display with Arduino / ATmega
(Deutsche Version) I bought this LCD module and this I2C controller. In this post, I will explain how to display text on the display. At first, you need the LiquidCrystal_I2C library from here. (I took the newest Version). Now you can directly start in the Arduino development enviroment. At first the includes:
Next, you have to define several things which are (in the library) not suitable for my LCD module:
Now you have to define the display:
Next, you can start in the setup()-function. At first, you have to tell the program what kind of display you have (the size, I have a 20 x 4 character display).
The rest is needed if you want to switch on the backlight with
Now you can write things onto the display:
To place the cursor at a specified position, you have to do the following:
This should cover all basic functions. To delete everything, simply call
A small hint, this problem took some time for me to solve: If you program an ATmega and then plug it into a pin board, usually nothing works, the ATmega needs a reset after it is plugged into the pin board. This could be caused by the fact that the ATmega already starts running when only some pins are connected to the pin board.
#include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h>
Next, you have to define several things which are (in the library) not suitable for my LCD module:
#define I2C_ADDR 0x20 #define BACKLIGHT_PIN 3 #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 #define LED_OFF 1 #define LED_ON 0
Now you have to define the display:
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
Next, you can start in the setup()-function. At first, you have to tell the program what kind of display you have (the size, I have a 20 x 4 character display).
lcd.begin (20,4);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(LED_ON);
The rest is needed if you want to switch on the backlight with
lcd.backlight();. Afterwards, the display is resetted: lcd.clear();
delay(1000);
lcd.home();
Now you can write things onto the display:
lcd.print("Hello, world!");
To place the cursor at a specified position, you have to do the following:
lcd.setCursor(5,1);
This should cover all basic functions. To delete everything, simply call
lcd.clear(); .A small hint, this problem took some time for me to solve: If you program an ATmega and then plug it into a pin board, usually nothing works, the ATmega needs a reset after it is plugged into the pin board. This could be caused by the fact that the ATmega already starts running when only some pins are connected to the pin board.
Subscribe to:
Posts (Atom)


