Už jsem pokročil a kompilace prochází bez chyb. Teď ještě bádám nad tím, kde by měly být správně výpisy na displej. V původním programu jsou řádky
a tak předpokládám, že tam by měly přijít ty výpisy.
Program je "neučesaná" pracovní verze. jsou tam nechané věci, co nejsou už potřeba a po konečném odladění přijdou smazat.
Špatně se to odlaďuje, protože čekat na bouřku dost dobře nejde a simulace zapalovačem není to nejlepší. Tápu kde by měl být výpis
a jak do výpisů dostat české znaky. Jestli to jde dát do jedné proměnné nebo to musím vypisovat po částech.
Doufám, že to není proti nějakému pravidlu, když jsem nežádal autory o svolení k úpravám.
Kód: Vybrat vše
/*
Modified to perform full scale detection and reporting by Glen Popiel - (kw5gp [at] hotmail.com)
Modified and added some functions by www.pablox.net pablox(at)pablox.net
-counter of total strikes
-added abiity to select indoor or outdoor mode by pin
-added logo on power on
-added accoustic output to beep on every strike
-added ability to send extra debug information via UART by shorting pin to ground + calibrate of AS3935 by shorting this pin to ground
-added ability to set minimum of strikes to made interrupt
-added sensor BMP180 for measuring temperature, barometric pressure and display then on LCD
Based on LightningDetector.pde - AS3935 Franklin Lightning Sensor™ IC by AMS library demo code
Copyright (c) 2012 Raivis Rengelis (raivis [at] rrkb.lv). All rights reserved.
Modified in 2013 for I2C by Luka Mustafa - Musti (musti [at] wlan-si.net).
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// BMP180 sensor i2c address is 0x77, sensor connected to i2c bus paralell with AS3935 board, supply of both chips must be 3,3V!
// I2c library by Wayne Truchsess
// I2C and AS3935 Libraries
#include "I2C.h" // Use the I2C Library
#include <AS3935.h> // Use the AS4935 Library
#include <LCD5110_Basic.h> // Use the Nokia 5110 LCD Library
#include <Wire.h> // Include the Wire Communication Library
#include <SFE_BMP180.h> // include BMP180 library
// BMP180
// create an SFE_BMP180 object, here called "pressure":
SFE_BMP180 pressure;
#include "I2C.h" // Use the I2C Library
#include <AS3935.h> // Use the AS4935 Library
#include <Wire.h> // Include the Wire Communication Library
#include <SFE_BMP180.h> // include BMP180 library
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
// ř
byte r_hacek[8] = {
B00101,
B00010,
B10110,
B11001,
B10000,
B10000,
B10000,
B00000
};
// š
byte s_hacek[8] = {
B00100,
B01010,
B01010,
B01010,
B01010,
B10001,
B10001,
B01110
};
// í
byte i_carka[8] = {
B00010,
B00100,
B01100,
B00100,
B00100,
B00100,
B01110,
B00000
};
// ý
byte y_carka[8] = {
B00001,
B00010,
B01001,
B01001,
B01111,
B00001,
B01110,
B00000
};
// é
byte e_carka[8] = {
B00010,
B00100,
B01110,
B10001,
B11111,
B10000,
B01110,
B00000
};
// šipka nahoru
byte sipka[8] = {
B00000,
B00100,
B01110,
B10101,
B00100,
B00100,
B00100,
B00000
};
//LCD5110 glcd(3,4,5,7,6); // Assign the Nokia 5110 LCD Pins
extern uint8_t SmallFont[]; // define the Nokia Font
extern uint8_t uvod_logo[]; // define startup logo
// Lightning Detector library object initialization First argument is interrupt pin, second is device I2C address
//!!! IF YOU HAVE BOARD WITH ANOTHER ADDRESS THAN 0, YOU MUST CHANGE IT !!!
AS3935 AS3935(2,0);
#define IRQ_PIN 2 // Define Pin 2 for the Interrupt from the Detector Module
#define SIMULATE_PIN 12 // Define Pin 12 for the Lightning Simulation switch
#define in_out_PIN 13 // Define pin 13 for indoor/outdooor/auto mode
#define spk_PIN 10 // Define pin 10 for speaker
#define diag_PIN 11 // Define pin 11 for full diagnostics via UART
#define EMI_PIN 8 // Define pin 8 for EMI
#define noise_PIN 9 // Define pin 9 for Noise High
#define holddown_time 20 // Delay to allow Detector Module settling after startup
#define AS3935_ENERGY_HIGH 0x6,0x1f // Defines the Register for the High order bits of the lightning energy
#define AS3935_ENERGY_MID 0x5,0xff // Defines the Register for the Middle order bits of the lightning energy
#define AS3935_ENERGY_LOW 0x4,0xff // Defines the Register for the Low order bits of the lightning energy
#define NoiseFloor 2 // Define the Noise Floor Level of the Detector Chip
#define SpikeReject 2 // Define the Spike Rejection Level of the Detector Chip
#define Watchdog 2 // Define the Watchdog Setting of the Detector Chip
#define minimum_lightnings 0 //define minimum of lightnings in 15 minutes to cause interrupt; 0: one lightning, 1: 5 lightnings, 2: 9 lightnings, 3: 16 lightnings
int strikes_total = 0;
int debug = 1;
int recommended_tune_cap=5; // Set the Recommended Value of the Detector Tuning Capacitor
int test; // calculated tuning cap valuecap
int strokeIntensity; // The intensity of the strike
int simulated; // Indicates if strike is simulated
int irqSource; // The source of the AS3935 interrupt
int strokeDistance; // the distance of the strike
int holddown = 1; // Set the Flag indicating startup
long last_event = 0; // Holds the time of the last event detected
long last_tick =0; // the time of the last minute "tick" in millis()
long current_time; // the current time in millis()
long time; // the difference in millis() between last "tick" and the last event
long time_mins; // when elapsed over 1 hour, here are minutes (1 hour and 10 minutes)
long time_mod; // save elapsed minutes before conversion to hours
double T,P; // Temperature and pressure
// Used to calcluate the intensity of the strike
long strokeEnergyHigh, strokeEnergyMid, strokeEnergyLow, strokeTotal;
// The lines of text for the Nokia display
String text1, text2, text3, text4, text5, text6, text7, text8, text9, text10, text11, text12, text13;
String data_buffer = " ";
LiquidCrystal_I2C lcd(0x23,20,4);
void setup()
{
Serial.begin(9600); // set the Serial USB port speed
lcd.init();
//I2C library initialization
I2c.begin();
I2c.pullup(true);
I2c.setSpeed(0); //100kHz
pinMode(IRQ_PIN, INPUT); // Setup the Detector IRQ pin
pinMode(diag_PIN, INPUT); // Setup the diagnostics pin
pinMode(SIMULATE_PIN, INPUT); // Setup the Lightning Simulate Button
digitalWrite(SIMULATE_PIN, HIGH); // enable the pullup resistor on the Simulate pin
digitalWrite(diag_PIN, HIGH); //enable the pull up on diagnostics pin
randomSeed(analogRead(0)); // seed the random number generator
simulated = LOW; // reset the simulate flag
pinMode(in_out_PIN, INPUT); // Setup the mode pin
digitalWrite(in_out_PIN, HIGH); // enable the pullup resistor on the in_out button
pinMode(spk_PIN, OUTPUT); // Setup the speaker PIN
pinMode(EMI_PIN, OUTPUT); // Setup the EMI
pinMode(noise_PIN, OUTPUT); // Setup the Noise High
lcd.createChar(1, r_hacek);
lcd.createChar(2, s_hacek);
lcd.createChar(3, i_carka);
lcd.createChar(4, y_carka);
lcd.createChar(5, e_carka);
lcd.createChar(6, sipka);
/* Set up the Nokia 5110 Display
glcd.InitLCD(65); // Initialize
glcd.setFont(SmallFont); // Use Small Font
cleartext(); // clear the text values
glcd.drawBitmap(0, 0, uvod_logo, 84, 48); // show startup logo
glcd.clrScr();
glcd.print("orig by kw5gp",CENTER,8);
glcd.print("mod pablox.net",CENTER,16);
glcd.print("init...",CENTER,32);
delay(10);
*/
// inicializace čidel
lcd.clear();
lcd.backlight();
lcd.setCursor(2,0);
lcd.print(" Inicializace.");
//if diagnostic pin is shorted do GROUND, sets debug flag to 1
if (digitalRead(diag_PIN) == LOW)
{
debug=1;
} else {
debug=0;
}
// BMP180 init - if fails, display message on UART
if (pressure.begin())
{
Serial.println("BMP180 init success");
text2="BMP180 OK";
lcd.setCursor(0,1);
lcd.print(text2);
updatelcd();
}
else
{
// BMP180 error
Serial.println("BMP180 init fail (disconnected?)\n\n");
text2="BMP180 ERR";
lcd.setCursor(0,1);
lcd.print(text2);
updatelcd();
while(1); // Pause forever.
}
// end of BMP180 init
if(debug == 0) // If the debug flag is set, provide extra diagnostic information
{
Serial.println("Scan I2C Bus"); // verify that we can see the Lightning Detector (should be at 0x3)
I2c.scan(); // Run the I2c Bus Scan function
}
Serial.println("Reset Detector");
// reset all internal register values to defaults
AS3935.reset(); // Reset the AS3935
delay(2000); // Wait a second for things to settle
// Set the Noise Floor, Spike Rejection and Watchdog settings
AS3935.setNoiseFloor(NoiseFloor); // Set the Noise Floor Level
delay(200);
AS3935.setSpikeRejection(SpikeReject); // Set the Spike Rejection Level
delay(200);
AS3935.setWatchdogThreshold(Watchdog); // Set the Watchdog Level
delay(1000);
AS3935.setMinimumLightnings(minimum_lightnings); // Set the minimum lightnings for interrupt
delay(1000);
AS3935.calibrate(); //start calibration procedure of AS3935
delay(500);
// if lightning detector can not tune tank circuit to required tolerance, shows message on LCD
if(!AS3935.calibrate()) {
cleartext();
text2="AS3935 ERR";
lcd.setCursor(0,2);
lcd.print(text2);
Serial.println("AS3935 ERR");
updatelcd();
}else
{
cleartext();
text2="AS3935 OK";
lcd.setCursor(0,2);
lcd.print(text2);
Serial.println("AS3935 OK");
updatelcd();
}
// konec inicializace
lcd.setCursor(0,3);
lcd.print("Konec inicializace.");
delay(3000);
lcd.clear();
// The Embedded Adventures MOD-1016 includes the recommended Tuning Capacitor Setting on the package
// This Debug calibration routine is for testing and verification purposes
if (debug == 0) // run calibration if debug flag set
{
// if lightning detector can not tune tank circuit to required tolerance,
// calibration function will return false
if(!AS3935.calibrate()) {
Serial.println("Tune Error");
}
// Set the Tuning Cap register to the value recommended
Serial.println("Set Tune Cap Reg");
AS3935.registerWrite(AS3935_TUN_CAP,recommended_tune_cap); // Write the recommended value to the Tuning Capacitor Register
delay(500); // Wait for things to settle
test = AS3935.registerRead(AS3935_TUN_CAP); // read and display the current Tuning Cap value
delay(500);
Serial.print("Tuning Cap: ");
Serial.println(test,HEX);
}
test = AS3935.registerRead(AS3935_TUN_CAP); // verify it is set correctly
delay(500);
Serial.print("Tuning Cap: ");
Serial.println(test,HEX);
// Display LCO frequency for 20 seconds. Uncomment below to use an oscilloscope
//or frequency counter to see LCO ffrequency. Frequency of LCO is divided by 16
// if LCO frequency is 500kHz, you see here 31.25 kHz +-3.5%
//*
Serial.println("Disp LCO frequency on IRQ pin :16");
AS3935.registerWrite(AS3935_DISP_LCO,1);
delay(100);
AS3935.registerWrite(AS3935_DISP_LCO,0);
Serial.println("LCO disp complete");
//*/
//Select mode Indoor/outdoor
if (digitalRead(in_out_PIN) == HIGH) // Check for a simulation
{
AS3935.setIndoors(); // Set Gain for Indoors
Serial.println("Mod doma");
text3="<-DUM->";
lcd.setCursor(5, 0);
lcd.print(text3);
updatelcd();
} else {
AS3935.setOutdoors(); // uncomment to set Gain for Outdoors
Serial.println("Mod venku");
text3="<-VENKU->";
lcd.setCursor(5, 0);
lcd.print(text3);
updatelcd();
}
delay(400); // Wait for things to Settle
// if debug flag is set to 1, EMI disturbers are allowed
if (debug == 0) // run calibration if debug flag set
{
AS3935.enableDisturbers(); } // Uncomment to turn on Disturber Interrupts (EMI)
else {
AS3935.disableDisturbers(); // We only want Lightning, turn off EMI interrupts
}
delay(400); // Wait for it things to settle
printAS3935Registers(); // Display the registers
int irqSource = AS3935.interruptSource(); // clear the IRQ before we start
delay(500);
Serial.println("Detektor Aktivni"); // And we're ready for lightning
// beep - init finished
for (int i=1; i<300; i++)
{
digitalWrite(spk_PIN,HIGH);
delayMicroseconds(1000);
digitalWrite(spk_PIN,LOW);
delayMicroseconds(500);
}
cleartext(); // Clear all the LCD text variables
bmp_readdata();
// výpis v klidu bez detekce
text3 = "Pozoruji";
text5 = String(strikes_total) +".";
lcd.setCursor(0, 1);
lcd.print(text3);
updatelcd(); // Update the LCD
} // End Setup Loop
void loop() // Start the Main Loop
{
// Check and update timestamp
current_time = abs(millis())/1000; // Current time (seconds since start)
if (current_time - last_tick >= 60) // Run if 60 seconds has passed
{
last_tick = current_time;
bmp_readdata(); //update data from BMP180 and display then on LCD
// convert to minutes and hours
time = last_tick - last_event; // convert difference last event to current time into seconds
if (time >=60 ) // One minute has passed
{
time = time/60;
text6 = String(time);
if ((time >= 1) && (time <60))
// 1 to 59 minutes ago
{
text6 = text6 + "min. stare";
} else {
if (time >=60)
{
time_mins = time - 60; // minutes over one hour to display in format XXh XXmin"
time_mod = time; // save elapsed time in minutes before conversion to hours
time = time/60;
// convert to hours
text6 = String(time);
if (time >=1)
{
if (time == 1)
{
text6 = text6 + "h:" + String(time_mins)+ "min. stare";
} else {
time_mins = time_mod - (60*time);
text6 = text6 + "h:" + String(time_mins)+ "min. stare";
}
}
}
}
// výpis času od poslední události
lcd.setCursor(5, 3);
lcd.print(text6);
updatelcd(); // Update the LCD with time since last event
}
}
if (holddown == 1) // Delay the start for a few seconds to let everything settle
{
if ((millis()/1000) > holddown_time) // If we've passed the hold down time
{
holddown = 0; // Turn it loose
}
} else {
// We've passed holddown time - rock and roll
if (digitalRead(SIMULATE_PIN) == LOW) // Check for a simulation
{
simulated = HIGH; // Turn on the simulated flag
delay(1000); // disable the simulate button for 1 second
} else {
simulated = LOW; // Make sure we turn off the simulated flag
}
if ((digitalRead(IRQ_PIN) == HIGH) || (simulated)) // If we have a real or simulated event let's do it
{
if (!simulated){ // if it's a real event, use the actual interrupt, otherwise set the IRQ code for lightning
delay(200); // wait for interrupt register to settle
irqSource = AS3935.interruptSource(); // Read the AS3935 IRQ Register
} else {
irqSource = 0b1000; // Set the IRQ code for lighting
}
// first step is to find out what caused interrupt
// as soon as we read interrupt cause register, irq pin goes low
// returned value is bitmap field, bit 0 - noise level too high, bit 2 - disturber detected, and finally bit 3 - lightning!
// create timestamp so we k when it occurred
if(irqSource != 0)
{ // 0 is a stat purge, we don't want to do anything with it
timestamp(); // Run the timestamp function
text6= "Novy "; // Set the Text time of the event to "Now"
bmp_readdata();
}
if (irqSource & 0b0001) // Noise Level High Interrupt
{
bmp_readdata();
//text2 = " "; // if lightning was detected in previous event, clears lines "Detected" and "Distance"
// text4 = " ";
// ?? výpis při detekci zvýšeného šumu
text7 = "Noise";
text5 = String(strikes_total) + ".";
lcd.setCursor(13, 2);
lcd.write (6);
lcd.setCursor(14, 2);
lcd.print(text7);
}
if (irqSource & 0b0100) // Man Made Disturber (EMI) Interrupt
// ?? výpis při velkém rušení EMI
{
text7 = "EMI ";
lcd.setCursor(13, 2);
lcd.write (6);
lcd.setCursor(14, 2);
lcd.print(text7);
}
if (irqSource & 0b1000) // Lightning
{
//beep
for (int i=1; i<100; i++)
{
digitalWrite(spk_PIN,HIGH);
delayMicroseconds(1000);
digitalWrite(spk_PIN,LOW);
delayMicroseconds(500);
}
//increment counter of total strikes
strikes_total = strikes_total + 1;
text5 = String(strikes_total) + ".";
// need to find distance of lightning strike, function returns approximate distance in kilometers,
// where value 1 represents storm in detector's near victinity, and 63 - very distant, out of range stroke
// everything in between is the distance in kilometers
//Detected
// text2 = " ";
if (simulated)
{ // make up a distance if we're faking it
strokeDistance = int(random(45)); // Pick a distance between 1 and 44)
if (strokeDistance < 5 ) // If a real strike is less than 5km, it's "Overhead", so we match that
{
strokeDistance = 1;
}
text1 = "Simulace";
} else { // otherwise, get the real distance
delay(8);
strokeDistance = AS3935.lightningDistanceKm(); // It's real lightning, read the AS3935 Distance Register
text1 = "Blesk!!! ";
}
if (strokeDistance < 5) // The AS3935 Reports Lightning distance as Out of Range,40,37,34,31,27,24,20,17,14,12,10,8,6,5,Overhead
{
text3 = "Nad hlavou";
}
if (strokeDistance > 40)
{
text3 = "Mimo dosah";
}
if (strokeDistance <= 40 && strokeDistance >= 5)
{
text3 = String(strokeDistance) + "km daleko";
}
if (simulated) // Make up the energy of the stroke
{
strokeEnergyHigh = int(random(31)); // There are 3 registers containing strike energy
strokeEnergyMid = int(random(255));
strokeEnergyLow = int(random(255));
} else { // otherwise get the real energy
strokeEnergyHigh = AS3935.registerRead(AS3935_ENERGY_HIGH); // Read the 3 Strike Energy Registers
strokeEnergyMid = AS3935.registerRead(AS3935_ENERGY_MID);
strokeEnergyLow = AS3935.registerRead(AS3935_ENERGY_LOW);
}
strokeTotal = strokeEnergyLow + (strokeEnergyMid*256)+ (strokeEnergyHigh*65536); // Calculate the total Strike Energy
strokeIntensity = map(strokeTotal,1,2000000,1,10); // map it to an Intensity factor of 1 thru 10
text4 = "Intensita:" + String(strokeIntensity);
}
if (irqSource == 0)
{
} else {
// výpis času
lcd.setCursor(5, 3);
lcd.print(text6);
// výpis vzdálenosti
lcd.setCursor(9, 1);
lcd.print(text3);
// hlášení blesku
lcd.setCursor(0, 1);
lcd.print(text1);
// počítadlo detekcí blesku
lcd.setCursor(0, 3);
lcd.print(text5);
// intenzita blesku
lcd.setCursor(0, 2);
lcd.print(text4);
// sem možná patří výpis text7
updatelcd(); // Update the LCD with the Event Data
if (irqSource & 0b1000)
{
data_buffer = String(strikes_total) + ". - " + String(strokeDistance) + " Km - " + "Intensita " + String(strokeIntensity) +
" - Tlak " + String(P+45,0) + "mbar - " + "teplota " + String (T,0) + "C -";
Serial.println(data_buffer);
}
}
}
}
} // End the Main Loop
void printAS3935Registers() // Display the basic AS3935 Registers
{
int noiseFloor = AS3935.getNoiseFloor(); // Read the Noise Floor setting
int spikeRejection = AS3935.getSpikeRejection(); // Read the Spike Rejection setting
int watchdogThreshold = AS3935.getWatchdogThreshold(); // Read the Watchdog Threshold setting
int min_lightnings = AS3935.getMinimumLightnings();
Serial.print("Noise floor: ");
Serial.println(noiseFloor,DEC);
Serial.print("Spike reject: ");
Serial.println(spikeRejection,DEC);
Serial.print("WD threshold: ");
Serial.println(watchdogThreshold,DEC);
Serial.print("Minimum lightnings: ");
Serial.println(min_lightnings,DEC);
}
void timestamp() // stores the time of the last event in seconds
{
last_event = abs(millis()/1000);
}
void updatelcd() // clears LCD display and writes the current LCD text data
{
}
void cleartext() // clears the text data
{
text1 = text1;
text2 = text1;
text3 = text1;
text4 = text1;
text3 = text1;
text4 = text1;
text5 = text1;
text6 = text1;
text7 = text1;
text8 = text1;
text9 = text1;
text10 = text1;
text11 = text1;
text12 = text1;
text13 = text1;
}
//function to read data from BMP180 sensor, display then on LCD and send them over UART
void bmp_readdata()
{
char status;
// You must first get a temperature measurement to perform a pressure reading.
// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.
// výpis teploty a tlaku
status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
text1 = String(T,0);
text1 = text1 + ((char)223)+"C";
//lcd.setCursor(0, 0);
//lcd.print(t1);
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.
// Přidaná korekce tlaku podle místa (+45):
status = pressure.getPressure(P,T);
if (status != 0)
{
text1 = String(T,0)+ ((char)223)+"C ";
text2 = String(P+45,0)+ "mbr";
}
}
}
}
lcd.setCursor(0,0);
lcd.print(text1);
lcd.setCursor(13,0);
lcd.print(text2);
updatelcd();
}