Show Posts
Pages: [1]
1  Using Arduino / Project Guidance / Re: Measuring AC line frequency on: October 08, 2013, 05:52:49 am
Hey all,

For your need, the simple setup described here work as well: http://blog.blinkenlight.net/experiments/measurements/power-grid-monitor-2/
Basically it does count the interrupts triggered to infer the mains frequency.
 
I did it myself, and it works pretty flawlessly, I just did a little twist to the code (not pretty, but works well) so it prints the frequency to the serial console.
I can post my code if needed.

However, I run into a little glitch when the arduino is not connected to the computer. (i.e powered by a wall adapter)
I added a Xbee radio so I can retrieve the frequency value wirelessly, however, when I don't share a GND with the computer (either via the USB connection, or via a simple USB-RS232 cable where I only use the GND), the frequency measurement is far off. I don't understand why, and the understanding of this problem might be a bit out of my league.

I will try some of the suggestions posted above to see if it's better. I reckon the optocoupler circuit might be a good idea as it ensures the arduino is a bit more protected. And it should work with the code of the above link.

Cheers,

Gromain


EDIT: Oh well, I might as well add my code, it's not secret after all!

Code:
//
//  www.blinkenlight.net
//
//  Copyright 2012 Udo Klein
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/
//
//  input capture = pin8 --> now how to exploit the display as good as possible
//
// Pins
// 01 00 08 --> used of serial connection and input capture IO

const uint8_t input_capture_pin = 8;


// helper type for efficient access of the counter structure
typedef union {
    uint32_t clock_ticks;
    struct {
        uint8_t  byte_0;
        uint8_t  byte_1;
        uint16_t word_1;
    };
} converter;



// Timing variables for sending
unsigned long now;
unsigned long next_send;
const unsigned long delay_send = 5000;

const String STATE = "STATE";
const char eom = ';'; //end of message
const char eol = '\n'; //end of line
const char sep = '~'; //separator for measures
const char initOrd = '>'; //first order character
const int waitingDelay = 50;

const String sensorName = "FREQ";    //Simple name to recognise the arduino on the Xbee Network

// Serial receive variables
char inputC;
String inputS;


// The timer values will be initialized nowhere.
// This works because we are intested in the differences only.
// The first differences will be meaningless due to lack
// of initialization. However they would be meaningless anyway
// because the very first capture has (by definition) no predecessor.
// So the lack of initialization semantically reflects this.
volatile converter input_capture_time;
volatile uint16_t timer1_overflow_count;

// 0 indicates "invalid"
volatile uint32_t period_length = 0;
volatile bool next_sample_ready = false;

ISR(TIMER1_OVF_vect) {
    ++timer1_overflow_count;
}

ISR(TIMER1_CAPT_vect) {
    static uint32_t previous_capture_time = 0;
   
    // according to the datasheet the low byte must be read first
    input_capture_time.byte_0 = ICR1L;
    input_capture_time.byte_1 = ICR1H; 
                             
    if ((TIFR1 & (1<<TOV1) && input_capture_time.byte_1 < 128)) {
        // we have a timer1 overflow AND
        // input capture time is so low that we must assume that it
        // was wrapped around
       
        ++timer1_overflow_count;   
         
        // we clear the overflow bit in order to not trigger the
        // overflow ISR, otherwise this overflow would be
        // counted twice
        TIFR1 = (1<<TOV1);
    } 
    input_capture_time.word_1 = timer1_overflow_count;
     
    period_length = input_capture_time.clock_ticks - previous_capture_time;
    previous_capture_time = input_capture_time.clock_ticks;
     
    next_sample_ready = true;
}

void initialize_timer1() {
    // Timer1: "normal mode", no automatic toggle of output pins
    //                        wave form generation mode  with Top = 0xffff
    TCCR1A = 0;

    // Timer 1: input capture noise canceler active
    //          input capture trigger on rising edge
    //          clock select: no prescaler, use system clock
    TCCR1B = (1<<ICNC1) | (1<< ICES1) | (1<<CS10);
   
    // Timer1: enable input capture and overflow interrupts
    TIMSK1 = (1<<ICIE1) | (1<<TOIE1);
   
    // Timer1: clear input capture and overflow flags by writing a 1 into them   
    TIFR1 = (1<<ICF1) | (1<<TOV1) ;
}


void visualize_frequency_deviation(const uint8_t target_frequency, const uint32_t period_length) {
   
    const int64_t deviation_1000 = 1000*(int64_t)F_CPU / period_length - 1000*(int64_t)target_frequency;
     
    Serial.print(F("period length  "));
    Serial.println(period_length);
     
    static int8_t sign = 1;
    if (deviation_1000 != 0) {
        // only compute new sign for frequency deviation != 0
        sign = deviation_1000 >= 0? 1: -1;
    }
   
    Serial.print(F("deviation: "));
    Serial.println((int32_t)deviation_1000);
   
    const uint64_t value = abs(deviation_1000);   
   
    Serial.print(F("value: "));
    Serial.println((uint32_t)value);
}


void setup() {

    Serial.begin(57600);

    // just to indicate which pins will be the output pins
    // this "output test" makes it easier to wire the circuit
    delay(1000);

    pinMode(input_capture_pin, INPUT);
    digitalWrite(input_capture_pin, HIGH);
    now = millis();
    next_send = now + delay_send;
    initialize_timer1();
}


const uint8_t target_frequency = 50;
const uint8_t sample_buffer_size = 50;
int64_t value_1000 = 0;

uint32_t sample_buffer[sample_buffer_size];


void loop() {
    static uint8_t sample_index = 0;
    now = millis();
    if (next_sample_ready) {
        next_sample_ready = false;
       
        cli(); // Disable global interrupts
        sample_buffer[sample_index] = period_length;   
        sei(); // Enable global interrupts
        sample_index = sample_index > 0? sample_index - 1: sample_buffer_size - 1;
       
        uint32_t average_period_length = 0;
        for (uint8_t index = 0; index < sample_buffer_size; ++index) {
            average_period_length += sample_buffer[index];
        }
        average_period_length /= sample_buffer_size;       
       
        value_1000 = 1000*(int64_t)F_CPU / average_period_length;
    }
    // boucle de comptage et tous les X tours (qui correspondent à 5s) envoie de la valeur en série
    if (now >= next_send) {
        Serial.print(sensorName);
        Serial.print(sep);
        Serial.print((int32_t)value_1000, DEC);
        Serial.println(eom);
        next_send = now + delay_send;
    }
}
2  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: November 17, 2012, 03:22:21 am
Hi everyone,


It seems nothing will do... Still got the same errors. The chip may be dead!

Well, too bad, but I'll use it for a reflow oven controller, so it won't need the usb communication!
At least, I'm reusing it!

Thanks again to everyone for the help!


Cheers,

Gromain
3  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: October 29, 2012, 12:32:54 am
Thanks for all the answers!

As for the USBtiny, I know it works well, I've used it to program the 328 with blink (to test the board, and it works well), and to put the bootloader back.

And the chip does power up when I connect the USBTiny. Should I try to connect the usb at the same time (to provide another power source for the chip while programming it)?
4  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: October 28, 2012, 12:35:13 pm
Hi!

Thanks for the help!

I tried your hint, but it seems there's some trouble with the chip itself...
Here is the error message I have when trying your command:
Code:
avrdude: initialization failed, rc=-1
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
avrdude: Expected signature for AT90USB82 is 1E 93 82
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.

avrdude done.  Thank you.


Device signature = 0x000000 ? That doesn't seem right, right?
Should I try with -D ?
5  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: October 28, 2012, 06:37:31 am
Yep! I just found out about it yesterday, and tried it right away! Nice improvement, but still no luck!

I was wondering that maybe I could use a usbtiny to reprogram the atmega 8u2... Would that be possible?
6  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: October 27, 2012, 02:12:11 pm
Thanks for the quick answers!

I tried the hdwwiz method, but when I changed the driver, it still didn't want to take the driver (I got something about the driver not being compatible with my device). I'm running Win7 in 64 bits, does this could be the reason? (i.e. no atmel dfu driver for win7 64bits?)

For your informations, the informations about the driver in the device manager are as follow:
Code:
Driver Provider: http://www.arduino.cc
Driver Date: 15/11/2007
Driver Version: 5.1.2600.0
Digital Signer: Not digitally signed

And the setting for the port are those:
Code:
Bits per second: 115200
Data bits: 8
Parity: None
Stop bits: 1
Flow control: None

No luck apparently!
7  Using Arduino / Installation & Troubleshooting / Re: Arduino won't upload on: October 27, 2012, 06:20:03 am
Hi everyone!

I do have the same problem! It seems I can't upload anything on my arduino UNO R2. I'm still able to upload sketches using an USBtiny, but no communication between the computer and the board when using the usb connection.
I got an "avrdude: stk500_getsync(): not in sync: resp=0x00" error when trying.
Although I followed the advices given here, I'm still stuck.

My board doesn't pass the loopback test.

The other problem is, I can't seem to be able to get the atmega 8u2 in DFU mode. It does nothing when I try to connect reset and GND from the pin on its side.
Well, to be honest, I think it did something the first time. I had a new device in the device manager (I'm using Win 7 64 bits here).
But the only driver accepted was the arduino one for the Uno board. It didn't accept the flip driver...

Any hints on what should I do now?

Thanks!
8  Forum 2005-2010 (read only) / Français / Re: gyroscope type rc avec arduino on: April 23, 2008, 08:10:34 am
Salut!!

Essaie d'insérer ce morceau là de code:

Code:
int valeur = analogRead(gyroIN);
 
Serial.println(valeur);
 
delay(10);

dans une boucle For pour le répéter 100 fois par exemple.
Il devrait alors te sortir une centaine de valeurs différentes.
Je ne connais pas ce type de produit, mais il semblerait qu'il sorte une nouvelle valeur toute les 1,5 ms, essaie donc de régler ton delay à 1,5! (C'est ce que j'ai compris après avoir fait un tour sur le lien que tu donne! Je ne suis pas un expert loin de là!)
Pages: [1]