//PER DISPLAY
//Anemometro collegato a:
// -> +5v
// -> D2 (con in parallelo una R 10Kohm verso massa)
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Adafruit_SSD1306.h"
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define OLED_SCREEN_WIDTH 128 // OLED display width, in pixels
#define OLED_SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT, &Wire, OLED_RESET); //oled
char sensorPrintout[6];
char sensorPrintoutMassimo[6];
float massimo;
char directionPrintout[3];
int direction;
int direction_180; //direzione per vela da 0 a +- 180
//PER SENSORE
#include <math.h>
#define WindSensorPin 2 // The pin location of the anemometer sensor
volatile unsigned long Rotations; // cup rotation counter used in interrupt routine
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in interrupt routine
float WindSpeed; // speed miles per hour
//1 Hz = 1,492mph = 2,4Km/h = 1,296Kn
const float K = 1.296;
bool avvio = true;
#define SCREEN_WIDTH 320 // OLED display width, in pixels
#define SCREEN_HEIGHT 240 // OLED display height, in pixels
int Xcentro;
int Ycentro;
float directionRad;
#define raggio 90
#define ANEMOMETER_SPEED_FACTOR 3.0 //if no specs available use this setting
#define ANEMOMETER_CIRCUMFERENCE_MTS 0.4367 // circumference in meters from center cup of anemometer
#define ANEMOMETER_CYCLES_PER_LOOP 1 // tipically cup anemometers count twice on a full loop
void isr_rotation () {
if((millis() - ContactBounceTime) > 20 ) { // debounce the switch contact.
Rotations++;
ContactBounceTime = millis();
Serial.print("Impulso:");
Serial.println(ContactBounceTime);
}
Serial.print("Impulso:");
Serial.println(Rotations);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Rotations\tMPH");
pinMode(WindSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
tft.begin();
tft.setRotation(1);
/*
tft.drawRect(0,0,10,10,ILI9341_WHITE);
// ------------------------------------------------------------------------------------------------
// drawLine(x start, y start,x end, y end, color)
// Draw line from x,y start to x,y end
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawLine");
tft.drawLine(5, 15, 100, 30, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// drawFastVLine(x, y, length, color)
// Draw a verticle line starting at x,y for the length of pixels
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawFastVLine");
tft.drawFastVLine(64, 16, 15, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// drawFastHLine(x, y, length, color)
// Draw a horizontal line starting at x,y for the length of pixels
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawFastHLine");
tft.drawFastHLine(64, 16, 15, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// drawTriangle(x1, y1, x2, y2, x3, y3, color)
// Draws a triangle from corner x,y point 1 to point 2 and then 3
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawTriangle");
tft.drawTriangle(5,15, 100,10, 64,30, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// fillTriangle(x1, y1, x2, y2, x3, y3, color)
// Draws and fills a triangle from corner x,y point 1 to point 2 and then 3
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("fillTriangle");
tft.fillTriangle(5,15, 100,10, 64,30, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// drawRect(x corner, y corner, width, height, color)
// Draws a rectangle from corner x,y with the width and height
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawRect");
tft.drawRect(64, 16, 30,10, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// fillRect(x corner, y corner, width, height, color)
// Draws and fills rectangle from corner x,y with the width and height
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("fillRect");
tft.fillRect(64, 16, 30,10, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// drawCircle(x center, y center, radius, color)
// Draws a circle x,y are the center of circle and radius length controls the size
// ------------------------------------------------------------------------------------------------
tft.fillScreen(ILI9341_BLACK);
Serial.println("drawCircle");
tft.drawCircle(64,16, 15, ILI9341_WHITE);
delay(2000);
// ------------------------------------------------------------------------------------------------
// fillCircle(x center, y center, radius, color)
// Draws and fills a circle x,y are the center of circle and radius length controls the size
// ------------------------------------------------------------------------------------------------
Serial.println("fillCircle");
tft.fillCircle(64,16, 15, ILI9341_WHITE);
delay(2000);
tft.fillScreen(ILI9341_BLACK);
*/
Xcentro = SCREEN_WIDTH/2;
Ycentro = SCREEN_HEIGHT/2;
Serial.println("drawRect");
// tft.drawRect(0, 180, 70, 50, ILI9341_WHITE);
// tft.drawRect(240, 180, 70, 50, ILI9341_WHITE);
ScriviGriglia(15,ILI9341_GREEN);
ScriviGriglia(30,ILI9341_GREEN);
ScriviGriglia(60,ILI9341_GREEN);
ScriviGriglia(90,ILI9341_WHITE);
ScriviGriglia(120,ILI9341_WHITE);
ScriviGriglia(150,ILI9341_WHITE);
ScriviGriglia(-15,ILI9341_RED);
ScriviGriglia(-30,ILI9341_RED);
ScriviGriglia(-60,ILI9341_RED);
ScriviGriglia(-90,ILI9341_WHITE);
ScriviGriglia(-120,ILI9341_WHITE);
ScriviGriglia(-150,ILI9341_WHITE);
tft.fillCircle(Xcentro,Ycentro, raggio, ILI9341_BLACK); //rinfresco il cerchio
tft.drawCircle(Xcentro,Ycentro, raggio, ILI9341_WHITE);
tft.drawCircle(Xcentro,Ycentro, raggio-20, ILI9341_WHITE);
}
void ScriviGriglia(int gradi, int colore)
{
tft.drawLine(Xcentro, Ycentro, Xcentro + (raggio + 10) * cos((gradi * PI/180) - PI / 2), Ycentro + (raggio +10) * sin((gradi * PI/180) - PI / 2), colore);
tft.drawLine(Xcentro, Ycentro, Xcentro + raggio * cos((gradi * PI/180) - PI / 2), Ycentro + raggio * sin((gradi * PI/180) - PI / 2), colore);
tft.setTextSize(2);
tft.setTextColor(colore);
int xDelta;
int yDelta;
if (gradi > 0){xDelta = 20; yDelta = 20;} else {xDelta = 45; yDelta = 20;}
tft.setCursor(Xcentro + (raggio + xDelta) * cos((gradi * PI/180) - PI / 2), Ycentro + (raggio + yDelta) * sin((gradi * PI/180) - PI / 2));
tft.println(abs(gradi));
}
void loop() {
//noInterrupts();
int xGradi= Xcentro-20;
int yGradi = Ycentro+50;
int xMax = Xcentro;
int yMax = Ycentro+25;
int xVento = Xcentro-(raggio/2);
int yVento = Ycentro-25;
// ANEMOMETRO
//1 campione al secondo = 1.296Kn
WindSpeed = (float)(((float)Rotations/3)/ANEMOMETER_CYCLES_PER_LOOP) * K; //Per campionamento ogni 3 sec
Rotations = 0; // Set Rotations count to 0 ready for calculations
//tft.fillScreen(ILI9341_BLACK);
//DISPLAY
if (WindSpeed>massimo && avvio == false)
{
massimo = WindSpeed;
tft.setTextSize(2);
tft.setCursor(xMax, yMax);
tft.setTextColor(ILI9341_BLACK);
tft.println(sensorPrintoutMassimo); //Cancello il testo solo se cambia il valore
}
//Cancello il vecchio valore
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(4);
tft.setCursor(xVento, yVento);
tft.println(sensorPrintout);
tft.setTextSize(2);
tft.setCursor(xGradi, yGradi);
tft.println(direction_180);
directionRad = direction * PI/180;
tft.drawLine(Xcentro, Ycentro, Xcentro + raggio * cos(directionRad - PI / 2), Ycentro + raggio * sin(directionRad - PI / 2), ILI9341_BLACK);
// DIREZIONE
int sensorValue = analogRead(A0);
float voltage = sensorValue*5/1023.0;
direction = map(sensorValue, 0, 1023, 0, 360);
if (direction>180)
direction_180 = abs(direction-360);
else
direction_180 = direction;
// print out the value you read:
Serial.print("ADC : ");
Serial.println(sensorValue);
Serial.print("Voltage : ");
Serial.println(voltage);
Serial.print("Direction : ");
Serial.println(direction);
Serial.print("DirectionRad : ");
Serial.println(directionRad);
Serial.print("direction_180 : ");
Serial.println(direction_180);
String sensorVal = String(WindSpeed,1);
String sensorMax = String(massimo,1);
String directionStr = String(direction_180,0);
sensorVal.toCharArray(sensorPrintout, 6);
sensorMax.toCharArray(sensorPrintoutMassimo, 6);
directionStr.toCharArray(directionPrintout,3);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(4);
tft.setCursor(xVento, yVento);
tft.println(sensorPrintout);
tft.setTextSize(2);
tft.setCursor(xMax-40, yMax);
tft.println("MAX");
tft.setCursor(xMax, yMax);
tft.println(sensorPrintoutMassimo);
tft.setTextSize(2);
tft.setCursor(xGradi, yGradi);
tft.println(direction_180);
tft.drawCircle(xGradi+40,yGradi, 3, ILI9341_WHITE);
//carcolo in radianti e disegno la linea
directionRad = direction * PI/180;
int x;
int y;
x=Xcentro + raggio * cos(directionRad - PI / 2);
y=Ycentro + raggio * sin(directionRad - PI / 2);
tft.drawLine(Xcentro, Ycentro, Xcentro + raggio * cos(directionRad - PI / 2), Ycentro + raggio * sin(directionRad - PI / 2), ILI9341_WHITE);
tft.drawLine(Xcentro, Ycentro, Xcentro + (raggio-20) * cos(directionRad - PI / 2), Ycentro + (raggio-20) * sin(directionRad - PI / 2), ILI9341_BLACK);
Serial.println("DisplayOled");
DisplayOled(WindSpeed,massimo);
avvio = false;
interrupts();
delay(3000);
}
void DisplayOled(float velocita, float max)
{
/*
display.clearDisplay() – all pixels are off
display.drawPixel(x,y, color) – plot a pixel in the x,y coordinates
display.setTextSize(n) – set the font size, supports sizes from 1 to 8
display.setCursor(x,y) – set the coordinates to start writing text
display.print(“message”) – print the characters at location x,y
display.display() – call this method for the changes to make effect
*/
Serial.print("velocita : ");
Serial.println(velocita);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
display.print(velocita) ;
display.print("kn - max: ") ;
display.print(max) ;
display.display() ;
}