gonium.net » arduino http://gonium.net/md so much time, so little to do. Sat, 11 Sep 2010 16:42:09 +0000 en hourly 1 http://wordpress.org/?v=3.0.1 DCF77 Radio Receiver – Filter Signals http://gonium.net/md/2009/09/16/dcf77-radio-receiver-filter-signals/ http://gonium.net/md/2009/09/16/dcf77-radio-receiver-filter-signals/#comments Wed, 16 Sep 2009 15:36:46 +0000 md http://gonium.net/md/?p=157 Broadcast Tower

I live close to the DCF77 radio transmitter, so my signal was always pretty strong and clear. This is of course not the case for everybody :-) Gwen Roelants did run into problems. He writes:

Although your code works (thanks for that!) it looked like it was very sensitive to how the antenna was positioned.
I found that I did receive a signal every second, but that for the longer signals, I sometimes got a short flash interrupting it, causing the library to add 2 seconds instead of one. Since I got such a flash in almost every minute it could take a very long time before a proper sync was found, and because 2 seconds were counted the time would also drift during the time no new signal could be decoded.
I found a rather simple fix for your code that greatly improved the reliability and time to find a correct signal.

I don’t have an Arduino around so I did not test it, but the proposed changes seem to be reasonable. You can find the changes in the Arduino forums. Thanks, Gwen!

The photo was CCed on flickr by Nathan Gibbs.

]]>
http://gonium.net/md/2009/09/16/dcf77-radio-receiver-filter-signals/feed/ 0
Tweaking the code http://gonium.net/md/2007/04/18/tweaking-the-code/ http://gonium.net/md/2007/04/18/tweaking-the-code/#comments Wed, 18 Apr 2007 14:54:47 +0000 md http://gonium.net/md/2007/04/18/tweaking-the-code/

Thanks to Lasse Lambrecht, I can release a new version of the DCF77 code – now you can run it on the ATMega168-based Arduinos.

The ATMega8 differs slightly from the ATMega48/88/168-series: The latter chips have an extended Timer2-hardware and therefore need different initializations. Lasse send me a nice adjustment of the code, basically he uses preprocessor flags to figure out which initialization commands to use: #ifdef ATMEGA168 TCCR2B |= (1<
  • arduino-dcf77-clock-0.2.1.tar.bz
  • For the hardware setup, please refer to my initial post. ]]>
    http://gonium.net/md/2007/04/18/tweaking-the-code/feed/ 12
    Using mySmartUSB programmer on Mac OS X http://gonium.net/md/2007/02/04/using-mysmartusb-programmer-on-mac-os-x/ http://gonium.net/md/2007/02/04/using-mysmartusb-programmer-on-mac-os-x/#comments Sun, 04 Feb 2007 18:25:25 +0000 md http://gonium.net/md/2007/02/04/using-mysmartusb-programmer-on-mac-os-x/ mySmartUSB in Action

    During the upgrade of my Arduino, I used the mySmartUSB programmer – initially on my Windows box, but since it’s USB and it mimics the AVR910 protocol, you can use it with avrdude on your Mac. Here’s how.

    Note: This currently only works for PowerPC-based Macs. Silicon Laboratories is not able to get a Intel Mac driver out – see http://www.surveyor.com/cgi-bin/yabb2/YaBB.pl?num=1161916754/4

    First of all, you need to install the USB driver for the chipset used in the programmer – it’s a CP2102 from Silicon Laboratories. You can download a driver from chip45. So go ahead and download it. Once it is installed, plug in the programmer. A file

    /dev/cu.SLAB_USBtoUART
    


    shows up – this is the USB-to-UART device that you can use with avrdude.I installed the latter using Macports, if you install it from another source, please make sure it is at least v5.3 – older versions do AFAIK not support the ATMega168.

    By default, the avrdude.conf does not contain the right device code for the AVR910 protocol. Open /opt/local/etc/avrdude.conf and make sure the following line is in the ATMega168 definition:

    avr910_devcode = 0x06;
    

    When everything is set, you can use the command

    avrdude -p m168 -P /dev/cu.SLAB_USBtoUART -c avr910 -t -u
    


    to get to avrdude’s terminal mode – you can use e.g. ‘sig’ to print the signature of your ATMega chip.

    You can buy the mySmartUSB programmer from myAVR – currently, it costs EUR 28,-.

    ]]>
    http://gonium.net/md/2007/02/04/using-mysmartusb-programmer-on-mac-os-x/feed/ 1
    Arduino on Steroids http://gonium.net/md/2007/01/23/arduino-on-steroids/ http://gonium.net/md/2007/01/23/arduino-on-steroids/#comments Tue, 23 Jan 2007 21:46:29 +0000 md http://gonium.net/md/2007/01/23/arduino-on-steroids/ steroids

    I just upgraded by little Arduino to the ATMega168 – and basically doubled the memory. But, be warned: This is not a hassle-free procedure if you have not some experience with microcontrollers.

    I bought a cheap serial programmer – only to figure out that the firmware is outdated and the ATMega168 is not supported. You can update the firmware – but you need another programmer for this *grmp*. So I bought a not-so-cheap mySmartUSB which runs over USB (so there is a chance it will work on the mac, I already found a driver for the USB chipset – stay tuned.)

    Today, most programmers come with a 10-pin header (aka Kanda connector), but the Arduino uses the old 6-pin ICSP header. I soldered a converter to solve this. Once I succeeded with the electrical connection, I failed in using avrdude – programming went fine, but I wasn’t able to set the fuse bits. Finally, I have found AvrOspII which worked perfectly on my Windows box. Please read Wolf Paulus’ description to save yourself a lot of time (and broken ATMegas) – he has written a great article about the fuse settings.

    If you’re interested in a pre-flashed Arduino, send me an email.

    PS: picture CC’ed by opk on flickr.

    ]]>
    http://gonium.net/md/2007/01/23/arduino-on-steroids/feed/ 0
    Arduino DCF77 v0.2 released http://gonium.net/md/2007/01/06/arduino-dcf77-v02-released/ http://gonium.net/md/2007/01/06/arduino-dcf77-v02-released/#comments Sat, 06 Jan 2007 22:52:15 +0000 md http://gonium.net/md/2007/01/06/arduino-dcf77-v02-released/ 4:57 nixietube clock

    The sketch for decoding the time radio signal DCF77 is greatly improved: I use interrupts for handling the signal and a backup timer has been added.

    Note that there is no interface at the moment, the time is simply put to the serial line. But it should be easy to add a display to show the time. The sketch eats roughly 6000 bytes of memory – if you want to add a user interface, you should consider buying a 16 kb Arduino ;-)

    Of course, you also need the DCF77 receiver module and a pullup-resistor, as described in my old post.

    You can download the code here:

    BTW: The picture above shows a Nixie tube clock. I ripped the picture shamelessly from flickr, there’s a photostream showing the creation of the clock. Cool project.

    ]]>
    http://gonium.net/md/2007/01/06/arduino-dcf77-v02-released/feed/ 14
    I will think before I code… http://gonium.net/md/2006/12/27/i-will-think-before-i-code/ http://gonium.net/md/2006/12/27/i-will-think-before-i-code/#comments Wed, 27 Dec 2006 09:54:04 +0000 md http://gonium.net/md/2006/12/27/i-will-think-before-i-code/ #include < avr / io.h > #define INIT_TIMER_COUNT 6 #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT int ledPin = 13; [...]]]> CosineKitty pointed out: My Arduino timer interrupt code did not work because the Prescaler bits were not set correctly. Applying basic boolean logic helps ;-) This is the working code: #include < avr / interrupt.h > #include < avr / io.h > #define INIT_TIMER_COUNT 6 #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT int ledPin = 13; int int_counter = 0; volatile int second = 0; int oldSecond = 0; long starttime = 0; // Aruino runs at 16 Mhz, so we have 1000 Overflows per second... // 1/ ((16000000 / 64) / 256) = 1 / 1000 ISR(TIMER2_OVF_vect) { RESET_TIMER2; int_counter += 1; if (int_counter == 1000) { second+=1; int_counter = 0; } }; void setup() { Serial.begin(9600); Serial.println("Initializing timerinterrupt"); //Timer2 Settings: Timer Prescaler /64, TCCR2 |= (1< "); Serial.print(millis() - starttime); Serial.println("."); digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); oldSecond = second; } } I will think before I code, I will think before I code, I will think before I code, ... The timer now works perfectly. I think the CTC mode will be more efficient, but my measurement shows that the clock has a slight skew (3 ms) when the Arduino starts up (lets say, during the first five minutes). Later, the skew is about zero. So the overflow mechanism is quite exact ;-) Note that the TIMER2 is used for PWM in the Arduino libraries, so this sketch might interfere with PWM applications - I did not test this.]]> http://gonium.net/md/2006/12/27/i-will-think-before-i-code/feed/ 24 Arduino Timer Interrupt http://gonium.net/md/2006/12/23/arduino-timer-interrupt/ http://gonium.net/md/2006/12/23/arduino-timer-interrupt/#comments Sat, 23 Dec 2006 22:12:02 +0000 md http://gonium.net/md/2006/12/23/arduino-timer-interrupt/ Continuing my interrupt experiments, I wrote a little sketch to print the seconds since startup to serial. But: Something is wrong…

    I use the Timer2 of the ATMega8. It consists of a 8 bit counter which is automatically increased. When an overflow occurs, the interrupt routine TIMER2_OVF_vect is called.

    This is the code:

    
    #include < avr / interrupt.h >
    #include < avr / io.h >
    
    #define INIT_TIMER_COUNT 0
    #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
    
    int ledPin = 13;
    int int_counter = 0;
    volatile int second = 0;
    int oldSecond = 0;
    
    // Aruino runs at 16 Mhz, so we have 61 Overflows per second...
    // 1/ ((16000000 / 1024) / 256) = 1 / 61
    ISR(TIMER2_OVF_vect) {
      int_counter += 1;
      if (int_counter == 61) {
        second+=1;
        int_counter = 0;
      }
    };
    
    void setup() {
      Serial.begin(9600);
      Serial.println("Initializing timerinterrupt");
      //Timer2 Settings:  Timer Prescaler /1024
      TCCR2 |= ((1 < < CS22) | (1 << CS21) | (1 << CS20));
      //Timer2 Overflow Interrupt Enable
      TIMSK |= (1 << TOIE2);
      RESET_TIMER2;
      sei();
    }
    
    void loop() {
      if (oldSecond != second) {
        Serial.print(second);
        Serial.println(".");
        oldSecond = second;
      }
    }
    
    

    Unfortunately, the counter is not increased every second but every three seconds. I need to investigate this. Anyway, it seems to be more reasonable to use the CTC mode (clear-timer-on-compare-match). I need to read the datasheet ;-)

    ]]>
    http://gonium.net/md/2006/12/23/arduino-timer-interrupt/feed/ 0
    Handling external Interrupts with Arduino http://gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/ http://gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/#comments Wed, 20 Dec 2006 21:11:53 +0000 md http://gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/ arduino-interrupt.jpg

    For my DCF77 clock project, I need an understanding of handling interrupts with the ATMega8 chip – here’s my sketch.

    The ATMega8 provides two pins (2 and 3) which can trigger software interrupts when the attached digital signal changes. You can use this to be “notified” when the external signal changes. Therefore, you do not need to poll the pin periodically – the interrupt routine will be invoked automatically when the specified signal change happens.

    In my case, I want to be notified when the DCF77 signal changes, so I need a simple way to exchange the current value of the pin. Here is the sketch:

    
    // Definition of interrupt names
    #include < avr/io.h >
    // ISR interrupt service routine
    #include < avr/interrupt.h >
    
    
    // LED connected to digital pin 13
    int ledPin = 13;
    // This is the INT0 Pin of the ATMega8
    int sensePin = 2;
    // We need to declare the data exchange
    // variable to be volatile - the value is
    // read from memory.
    volatile int value = 0;
    
    // Install the interrupt routine.
    ISR(INT0_vect) {
      // check the value again - since it takes some time to
      // activate the interrupt routine, we get a clear signal.
      value = digitalRead(sensePin);
    }
    
    
    void setup() {
      Serial.begin(9600);
      Serial.println("Initializing ihandler");
      // sets the digital pin as output
      pinMode(ledPin, OUTPUT);
      // read from the sense pin
      pinMode(sensePin, INPUT);
      Serial.println("Processing initialization");
      // Global Enable INT0 interrupt
      GICR |= ( 1 < < INT0);
      // Signal change triggers interrupt
      MCUCR |= ( 1 << ISC00);
      MCUCR |= ( 0 << ISC01);
      Serial.println("Finished initialization");
    }
    
    void loop() {
      if (value) {
        Serial.println("Value high!");
        digitalWrite(ledPin, HIGH);
      } else {
        Serial.println("Value low!");
        digitalWrite(ledPin, LOW);
      }
      delay(100);
    }
    
    

    In the main loop, the value gets interpreted, but not read. This happens in the interrupt handler routine. The routine is installed with the avrgcc preprocessor macro “ISR” – this way, we do not need to fiddle with the interrupt vector directly. During the setup function, be careful to initialize the ATMega8 correctly – in this case, we need to enable the INT0 interrupt. With the MCUCR register, we can change the way the interrupt gets triggered – here, we receive an interrupt when the signal changes in both directions (HIGH -> LOW and LOW -> HIGH).

    The wiring for the testing is rather simple: Use a breadboard and power it from the Arduino. Connect a pull-up resistor to positive and the other end to pin 2 of your Arduino. Connect an additional cable from the “other end” of the resistor to negative. If you pull the latter cable from negative, the current on pin 2 will go to HIGH, if you reconnect it to negative, it will go to LOW. You could also use a switch, of course ;-)

    If you speak german, I highly recommend the “AVR-GCC Tutorial” of mikrocontroller.net.

    ]]>
    http://gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/feed/ 10
    Arduino DCF77 radio clock receiver http://gonium.net/md/2006/11/05/arduino-dcf77-radio-clock-receiver/ http://gonium.net/md/2006/11/05/arduino-dcf77-radio-clock-receiver/#comments Sun, 05 Nov 2006 20:31:08 +0000 md http://gonium.net/md/2006/11/05/arduino-dcf77-radio-clock-receiver/ DCF77-arduino.jpg

    As a first sketch, I developed a little DCF77 library for the arduino. The DCF77 sender broadcasts the exact time in Germany. It uses a binary format which needs to be decoded – which is exactly what the library does.

    There are others around who wrote a DCF77 decoder: I would like to thank Captain for his DCF77 code. You need to have an Arduino and a DCF77 receiver in order to use this sketch.

    I use the “DCF-Empfänger BN 641138″ of Conrad. You need a pull-up resistor as displayed here:

    arduino-dcf77-setup.jpg

    arduino-dcf77-schematic.jpg

    When everything is connected, the exact time is printed on the serial line. Note that this is a very early release of the software – there is a lot of functionality missing. From the README:

    The current todo list is:
     * Use interrupt routines for detecting signal changes
     * Use interrupt routines to add seconds automatically
       (currently, the 59th second is shown properly)
     * Implement parity checks to prevent faulty time
       signals to be evaluated
    

    The sketch eats up 6400 of the 7168 bytes in the Arduino. I am currently considering to upgrade my board to the ATMega 168 processor in order to have 16kb of memory…

    You can download the code here:


    The code is released under terms of the CC-GNU GPL.

    ]]>
    http://gonium.net/md/2006/11/05/arduino-dcf77-radio-clock-receiver/feed/ 24