AdSense

Monday 17 February 2014

A free tool to draw circuits

(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.

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:
  • A microcontroller (ATmega / Arduino)
  • 3 bipolar transistors (NPN) which can handle enough current!
The microcontroller sends 3 PWM signals to the base of the transistors (apply pre-resistors, I use 470 Ohms). The emitter of the transistors is connected to ground (a common ground of the 12 V power supply and the microcontroller), the collector is connected to the corresponding colour channel.

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.

#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.