Arduino EMF

From YobiWiki
Revision as of 21:04, 19 October 2009 by <bdi>PhilippeTeuwen</bdi> (talk | contribs) (Created page with 'Back to Arduino page. Based on [http://www.aaronalai.com/emf-detector Aaron's detector], here using a 2x16 LCD, actually my VFD. <br>Upper row gives the averaged value on 10…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Back to Arduino page.

Based on Aaron's detector, here using a 2x16 LCD, actually my VFD.
Upper row gives the averaged value on 10 samples
Lower row gives the signal between the minimal and maximal values observed in the 10 samples.
It's also a good example of a smooth bargraph on a LCD, with custom "chars" if needed.
It is using the library

You can download the code [{{#file: testEMF.pde}} as testEMF.pde]

// Doegox EMF detector
// Based on Aaron ALAI EMF Detector April 22nd 2009 VERSION 1.0

#include <LiquidCrystal.h>

int inPin = 5;             // analog 5
#define MAXN 10            // samples per cycle
#define FREQ 50            // cycle in Hz, 60 for US folks
#define DARKBARS true      // extrapolate 2 bars between digits? smoother but we loose info

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(2, 16); 
  lcd.clear();
}

void loop() { 
  int val;
  int val_avg = 0;           // will store and average value of analog 5
  int val_min = 1024;        // will store and keep min value of analog 5
  int val_max = 0;           // will store and keep max value of analog 5
  int LCD1[16];              // will store temporarely content of 2nd LCD row

  for (int n=0; n<MAXN; n++) {
    delayMicroseconds(1000000/FREQ/MAXN);
    val = analogRead(inPin);
    val_avg += val;
    val_min = min(val_min, val);
    val_max = max(val_max, val);
  }
  val_avg/=MAXN;
  val_avg = map(val_avg, 0, 1023, 1, 16*(DARKBARS ? 7 : 5));
  val_min = map(val_min, 0, 1023, 1, 16*(DARKBARS ? 7 : 5));
  val_max = map(val_max, 0, 1023, 1, 16*(DARKBARS ? 7 : 5));

  lcd.setCursor(0,0);
  for (int i=0; i<16;i++) {
    if (val_avg>=5) {
      lcd.print(0x14, BYTE);
      val_avg-=min((DARKBARS ? 7 : 5),val_avg);
    } else if (val_avg>=1) {
      lcd.print(0x0F + val_avg, BYTE);
      val_avg=0;
    } else {
      lcd.print(0x20, BYTE);
    }
  }
  for (int i=0; i<16;i++) {
    if (val_min>=6) {
      LCD1[i]=0x20;
      val_min-=min((DARKBARS ? 7 : 5),val_min);
      val_max-=min((DARKBARS ? 7 : 5),val_max);
    } else if (val_min>=1) {
      if (val_max>=5) {
        LCD1[i]=0x13 + val_min;
        val_max-=min((DARKBARS ? 7 : 5),val_max);
      } else {
        // tricky part, both min & max on same digit
        int mm=0;
        uint8_t mmchr[8];
        for (int k=4; k>=0; k--) {
          if ((k + val_min <= 5) && (k + val_max >=5 ))
            mm+=1<<k;
        }
        for (int k=0; k<7; k++)
          mmchr[k]=mm;
        mmchr[7]=0x00;
        // here we risk to manipulate again a char being displayed
        // for critical apps, better to work on an unused char
        // e.g. toggle between CG-RAM 0x00 and CG-RAM 0x01
        lcd.createChar(0x00, mmchr);
        LCD1[i]=0x00;
        val_max=0;
      }
      val_min=0;
    } else {
      if (val_max>=5) {
        LCD1[i]=0x14;
        val_max-=min((DARKBARS ? 7 : 5),val_max);
      } else if (val_max>=1) {
        LCD1[i]=0x0F + val_max;
        val_max=0;
      } else {
        LCD1[i]=0x20;
      }
    }
  }
  lcd.setCursor(0,1);
  for (int i=0; i<16;i++) {
    lcd.print(LCD1[i], BYTE);
  }
}