copter
Last Man Standing
- Liittynyt
- 05.12.2016
- Viestejä
- 3 310
Tässäpä tämä koodi jonka sain kaivettua esille. Pitäisi mennä ihan copy pastella sisään Arduino ideen. Koodin lisäksi näyttöä käytettäessä tarvitaan Adafruit GFX ja SSD1306 kirjasto, johon pitää editoida käytettävissä olevan taulun resoluutio esim. tämän ohjeen mukaan.
Pikasesti tuon joskus väänsin, eli ei mitään kauneinta katsottavaa. Pitäisi kuitenkin toimia.
Koodi:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// -- INIT: TEMPERATURE
// which analog pin to connect
#define THERMISTORPIN A0
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// how many samples to take and average, more takes longer but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000
uint16_t samples[NUMSAMPLES];
// -- INIT: LCD
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
// -- INIT: RPM
String rpm;
// -- INIT: SETUP
void setup(void) {
// init rpm variable
rpm = "---";
// init serial line via usb
Serial.begin(9600);
// init lcd
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.display();
// init pwm output
// configure hardware timer2 to generate a fast PWM on OC2B (Arduino digital pin 3)
// set pin high on overflow, clear on compare match with OCR2B
TCCR2A = 0x23;
TCCR2B = 0x0C; // select timer2 clock as 16 MHz I/O clock / 64 = 250 kHz
OCR2A = 249; // top/overflow value is 249 => produces a 1000 Hz PWM
pinMode(3, OUTPUT); // enable the PWM output (you now have a PWM signal on digital pin 3)
// initial value 100%
OCR2B = 255;
}
void loop(void) {
// measure temp
uint8_t i;
float average;
// take N samples in a row, with a slight delay
for (i=0; i< NUMSAMPLES; i++) {
samples[i] = analogRead(THERMISTORPIN);
delay(10);
}
// average all the samples out
average = 0;
for (i=0; i< NUMSAMPLES; i++) {
average += samples[i];
}
average /= NUMSAMPLES;
// print some debug
Serial.print("Average analog reading ");
Serial.println(average);
// convert the value to resistance
average = 1023 / average - 1;
average = SERIESRESISTOR / average;
// print some debug
Serial.print("Thermistor resistance ");
Serial.println(average);
// now to the hard part, calculate steinhart
float steinhart;
steinhart = average / THERMISTORNOMINAL; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15; // convert to C
// print some debug
Serial.print("Temperature ");
Serial.print(steinhart);
Serial.println(" *C");
// set fan control value
// default
int fvalue = 55;
// control "steps" are here hardcoded, not nice or fancy but works.
// TODO: add linear adjustement between points
if(steinhart < 27.0) fvalue = 55;
if(steinhart >= 27.0) fvalue = 67;
if(steinhart >= 28.0) fvalue = 79;
if(steinhart >= 29.0) fvalue = 90;
if(steinhart >= 30.0) fvalue = 102;
if(steinhart >= 31.0) fvalue = 114;
if(steinhart >= 32.0) fvalue = 126;
if(steinhart >= 33.0) fvalue = 137;
if(steinhart >= 34.0) fvalue = 149;
if(steinhart >= 35.0) fvalue = 161;
if(steinhart >= 36.0) fvalue = 173;
if(steinhart >= 37.0) fvalue = 184;
if(steinhart >= 38.0) fvalue = 196;
if(steinhart >= 39.0) fvalue = 208;
if(steinhart >= 40.0) fvalue = 220;
if(steinhart >= 41.0) fvalue = 231;
if(steinhart >= 42.0) fvalue = 255;
OCR2B = fvalue;
// print some debug
Serial.print("PWM ");
Serial.println(fvalue);
// try to get rpm value via serial
if (Serial.available() > 0) {
rpm = Serial.readString();
rpm = rpm.substring(0,rpm.indexOf(';'));
// print some debug
Serial.print("RPM ");
Serial.println(rpm);
}
// put it to screen
display.clearDisplay();
display.setTextColor(WHITE);
// sensor
display.setCursor(0,0);
display.setTextSize(4);
display.println(steinhart);
// rpm
display.setCursor(0,33);
display.setTextSize(2);
display.println(rpm + " RPM");
// control value
double percentage = ((double) fvalue / 255) * 100;
display.setCursor(0,50);
display.setTextSize(2);
display.print(percentage);
display.println(" %");
// show screen
display.display();
// wait 1 second until we do all over again
delay(1000);
}
Pikasesti tuon joskus väänsin, eli ei mitään kauneinta katsottavaa. Pitäisi kuitenkin toimia.