AdSense

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):

                      +---\/---+
           (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:

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) {}

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:

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

Sunday, 29 September 2013

Raspberry PI - C++ - Open socket

(Deutsche Version) Today, I want to show how to open a socket in C++. The reason for this post is: I have a Raspberry PI who does lot of things like reading temperature, controlling several things in the house. Handling the communication to the Raspberry PI via files is not a good solution, so I want to communicate directly vie network with the Raspberry PI. Therefore, the Raspberry PI has to open a network socket. I copied the code from other sources and adapted it a bit. I only need the receiving and the sending of messages. I also defined the message length to 256 bytes. The code for opening a socket is the following:

//define variables 
int sockfd, newsockfd, portno = 82; //number of port
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n; 
 
//create socket 
sockfd = socket(AF_INET, SOCK_STREAM, 0);

bzero((char *) &serv_addr, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);

bind(sockfd, (struct sockaddr *) &serv_addr,
        sizeof(serv_addr));
listen(sockfd,5);
clilen = sizeof(cli_addr); 
 
//accept tcp clients 
while(true)
{
  //accept client 
  newsockfd = accept(sockfd, 
            (struct sockaddr *) &cli_addr, 
            &clilen); 
  bzero(buffer,256);
  //read client message into buffer
  n = read(newsockfd,buffer,256);
  //write message to client
  n = write(newsockfd,"I got your message, this should be 256 bytes long",256);

  close(newsockfd);
}
close(sockfd);

Friday, 27 September 2013

Raspberry PI - C++ - Threads

(Deutsche Version) Implementing threads in C# is pretty simple. To use threads with C++ on a Raspberry PI, you have to do some small things which are not necessary in C#. You have to place #include <thread> on the top. Then you can create a thread like this:

std::thread networkThread (networkCommunication);
networkThread.detach();


To compile this program, you have to add two things to the compile command in the terminal:

-std=c++0x
-pthread


The whole program is compiled like this:

g++ ./myProgram.c++ -o outputName -std=c++0x -pthread

Now you should be able to create threads on your Raspberry PI.

Tuesday, 24 September 2013

The influence of the Coriolis force on a sniper bullet

(Deutsche Version) Some time ago, I watched the film Shooter (Wikipedia). In the early stages, a shot over a distance of 1,5 km is mentioned. It is also mentioned that for such a shot, even the Coriolis force has an effect. Today, I want to calculate this.

At first a short introduction about the topic Coriolis force. The Coriolis force is one of the pseudo forces which occurs in rotating frames. The force can be derived simply by transforming the equation of motion of a free particle into a rotating frame (for more information, see e.g. H.-R. Trebin, Theoretische Physik 1, Mechanik). For my calculation, this is not necessary. Basically, the Coriolis force occurs because the earth turns away under the projectile.

Let's face the calculation. To get a maximum influence of the Coriolis force, I assume that the shot is parallel to a line of longitude. Assuming a degree of latitude of 45°, the target is about 1 km farther from the rotation axis of the earth, so the target moves quicklier perpendicular to the trajectory than the projectile. Now I want to calculate these velocities. The diameter of the earth is about 12730 km. In the 45. degree of latitude, this equals a radius of about 4500 km, leading to a perimeter of 28274 km. With a time of circulation of 86400 seconds, this leads to a velocity of 327.245 m/s. If the radius is increased about 1 km, the new perimeter is 28281 km and the new velocity 327.326 m/s. This causes a difference of 0.081 m/s.

In the film, a time of flight of 6 to 10 seconds is mentioned, this would cause a deviation of 0.5 to 0.8 meters. I personally think that the time of flight is much shorter, a projectile with 1000 m/s only needs 1.5 seconds for this distance, so the deviation is about 12 cm (which still could decide wheter it is a hit or not).