Go Down

Topic: Measure nightsky with TSL237 (Read 13576 times) previous topic - next topic

Corpze

I am learning along here, i am trying out different float, unsigned longs etc... i have also got my "cheat-code" to work... i tried the freqmeasure.h and that worked like a charm...

don´t get me wrong here, i like to learn and i am listening to all of you! big thumbs up for you guys! So while i try to compile my "own" code i also trying librarys with examplecode...

just sharing what i tried yesterday, i also tried to add a button so i can choose when i want to take a reading.


Code: [Select]
#include <LiquidCrystal.h>
#include <FreqMeasure.h>
#include <Math.h>

LiquidCrystal lcd (12, 11, 10, 9, 7, 6);
float Msqm;
const float A = 22;
int buttonSQM = A2;

void setup() {
   Serial.begin(19200);
   FreqMeasure.begin();
   pinMode(buttonSQM, INPUT);
   digitalWrite(buttonSQM, HIGH);
   lcd.begin(16,2);
}

double sum=0;
int count=0;

void loop() {
   if (buttonSQM = digitalRead(HIGH));{
     if (FreqMeasure.available()) {
      // average several reading together
     sum = sum + FreqMeasure.read();
     count = count + 1;
     if (count > 30) {
     double frequency = F_CPU / (sum / count);
     Serial.println(frequency);
     sum = 0;
     count = 0;

     Msqm = A - 2.5*log10(frequency); //Egen Kod
     Serial.print(Msqm);
     Serial.println(" Mag/Arcsecond2 ");
}
}
}
}

afremont

#76
Mar 07, 2013, 06:32 pm Last Edit: Mar 07, 2013, 06:42 pm by afremont Reason: 1
If you want an accurate measurement of the period of a waveform, this code will do the job.  It doesn't tie up the foreground and it doesn't write to the timer or disable interrupts at all.  Pin change interrupts are ok, but lack the absolute precision that the capture facility will give you.  You feed your signal in on Pin 8 to use this code.  This program computes the period of a waveform in microseconds.  To calculate frequency take the inverse.  The period is an unsigned long so the maximum period is 232-1 microseconds.  Just delete the circular buffer stuff if you don't need it.  Don't forget to set the t1captured flag in the capture ISR handler.  This is the most accurate method there is to measure a wave period with the 328p.


Code: [Select]

#include "Arduino.h"

volatile unsigned t1captured = 0;
volatile unsigned t1capval = 0;
volatile unsigned t1ovfcnt = 0;
volatile unsigned long t1time;
volatile unsigned long t1last = 0;

#define BUFFER_SIZE 32

volatile unsigned long int buffer[BUFFER_SIZE];
volatile int head = 0;
volatile int tail = 0;

void setup() {

 Serial.begin(9600);  

 TCCR1A = 0x0;    // put timer1 in normal mode
 TCCR1B = 0x2;    // change prescaler to divide clock by 8

 // clear any pending capture or overflow interrupts
 TIFR1 = (1<<ICF1) | (1<<TOV1);
 // Enable input capture and overflow interrupts
 TIMSK1 |= (1<<ICIE1) | (1<<TOIE1);
 
 pinMode(8, INPUT);
}

void loop() {

 if(head != tail) {
   head = (head + 1) % BUFFER_SIZE;
   Serial.println(buffer[head]);
 }

//  if(captured == 1) {
//    Serial.println(tltime);
//    t1captured = 0;
//  }
 
}

ISR(TIMER1_OVF_vect) {
 
  t1ovfcnt++;              // keep track of overflows

}


ISR(TIMER1_CAPT_vect) {
 
 unsigned long t1temp;

 // combine overflow count with capture value to create 32 bit count
 //  calculate how long it has been since the last capture
 //   stick the result in the global variable t1time in 1uS precision
 t1capval = ICR1;
 t1temp = ((unsigned long)t1ovfcnt << 16) | t1capval;
 t1time = (t1temp - t1last) >> 1;         // divide by 2 to convert to microseconds
 t1last = t1temp;
 
//t1captured = 1;           // set flag for main level to see that capture is done

// delete the next two lines if you don't need the buffer
 tail = (tail + 1) % BUFFER_SIZE;
 buffer[tail] = t1time;

}
Experience, it's what you get when you were expecting something else.

GoForSmoke


I am learning along here, i am trying out different float, unsigned longs etc... i have also got my "cheat-code" to work... i tried the freqmeasure.h and that worked like a charm...

don´t get me wrong here, i like to learn and i am listening to all of you! big thumbs up for you guys! So while i try to compile my "own" code i also trying librarys with examplecode...

just sharing what i tried yesterday, i also tried to add a button so i can choose when i want to take a reading.


Good move with the button.

When you use floating point constants like the 22 in
Code: [Select]
const float A = 22;

it's good to put in a decimal just to be sure, like how the UL goes on
Code: [Select]
const unsigned long U = 12345UL;

and usually people would write 22.0 instead of 22., I guess for easy reading.

Most of the time the compiler will get it right or it won't matter but it can gitcha and those bugs can be a real pain.

Keep on with the updates!



Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Corpze



I am learning along here, i am trying out different float, unsigned longs etc... i have also got my "cheat-code" to work... i tried the freqmeasure.h and that worked like a charm...

don´t get me wrong here, i like to learn and i am listening to all of you! big thumbs up for you guys! So while i try to compile my "own" code i also trying librarys with examplecode...

just sharing what i tried yesterday, i also tried to add a button so i can choose when i want to take a reading.


Good move with the button.

When you use floating point constants like the 22 in
Code: [Select]
const float A = 22;

it's good to put in a decimal just to be sure, like how the UL goes on
Code: [Select]
const unsigned long U = 12345UL;

and usually people would write 22.0 instead of 22., I guess for easy reading.

Most of the time the compiler will get it right or it won't matter but it can gitcha and those bugs can be a real pain.

Keep on with the updates!






I tried to add a decimal (22.0) to the const float;

Code: [Select]
4.44
20.38 Mag/Arcsecond2
4.58
20.35 Mag/Arcsecond2
4.53
20.36 Mag/Arcsecond2
1.34
21.68 Mag/Arcsecond2
2.75
20.90 Mag/Arcsecond2
4.46
20.38 Mag/Arcsecond2
4.26
20.43 Mag/Arcsecond2
4.25
20.43 Mag/Arcsecond2
4.22
20.44 Mag/Arcsecond2
3.87
20.53 Mag/Arcsecond2
0.86
22.16 Mag/Arcsecond2
3.69
20.58 Mag/Arcsecond2


And this is without the decimal;

Code: [Select]

3.64
20.60 Mag/Arcsecond2
3.81
20.55 Mag/Arcsecond2
3.97
20.50 Mag/Arcsecond2
4.18
20.45 Mag/Arcsecond2
4.19
20.44 Mag/Arcsecond2
3.49
20.64 Mag/Arcsecond2
3.72
20.57 Mag/Arcsecond2
3.78
20.56 Mag/Arcsecond2
3.66
20.59 Mag/Arcsecond2
3.53
20.63 Mag/Arcsecond2
3.40
20.67 Mag/Arcsecond2


Can´t see any difference, but as you say, there might be problems later on without the decimal?

GoForSmoke

It's just about making sure there won't be a problem. Every so often you see a problem posted here where it makes a difference. Most of the time there won't be and that's when habits get developed that go unquestioned even while debugging.

But it's up to you. Adding .0 doesn't make the code bigger but does take time.

It's like using floats and getting .999999 instead of 1.0. It doesn't happen every time and anyway if close enough is good enough then that's a call to make. Heck, in physics we used 10 m/s/s for Earth gravity instead of 9.81 and took some other shortcuts that were close enough for school BC (before calculators).


Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

minaya

Afremont's example of InputCapture use is just awesome. Thanks for posting it here!.

afremont

You're welcome!   Glad you found it useful.
Experience, it's what you get when you were expecting something else.

Go Up