#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#define SSD1306_WIDTH 128 // OLED display width, in pixels
#define SSD1306_HIGHT 64 // OLED display height, in pixels
#define SSD1306_ADDRESS 0x3C
#define OLED_RESET -1 // can set an oled reset pin if desired
#define SHIFT_RESISTOR_DS_PIN 7 // シリアルデータ
#define SHIFT_RESISTOR_SHCP_PIN 8 // シリアルクロック
#define SHIFT_RESISTOR_STCP_PIN 9 // ラッチ
#define PHOTORESISTOR_SENSOR_AO_PIN A0 // フォトレジスタ アナログ出力ピン
#define SERVO_MOTOR_PWM_PIN 10 // サーボモーター PWMピン
// LDR Characteristics
const float GAMMA = 0.7;
const float RL10 = 50;
union ShiftResistorData {
uint16_t data_16;
uint8_t data_8[2];
};
struct PhotoResistorData {
float voltage;
float resistance;
float lux;
};
PhotoResistorData getPhotoResistorData();
void dispLcd(PhotoResistorData data);
void dispLed(PhotoResistorData data);
void rotateServo(PhotoResistorData data);
Adafruit_SSD1306 ssd1306(SSD1306_WIDTH, SSD1306_HIGHT, &Wire, OLED_RESET);
Servo servo;
void setup() {
//Serial.begin(115200);
pinMode(PHOTORESISTOR_SENSOR_AO_PIN, INPUT);
pinMode(SHIFT_RESISTOR_DS_PIN, OUTPUT);
pinMode(SHIFT_RESISTOR_SHCP_PIN, OUTPUT);
pinMode(SHIFT_RESISTOR_STCP_PIN, OUTPUT);
servo.attach(SERVO_MOTOR_PWM_PIN);
servo.write(0);
ssd1306.begin(SSD1306_SWITCHCAPVCC, SSD1306_ADDRESS);
ssd1306.setTextColor(SSD1306_WHITE);
ssd1306.setTextSize(1);
}
void loop() {
PhotoResistorData data = getPhotoResistorData();
dispLcd(data);
dispLed(data);
rotateServo(data);
delay(100);
}
PhotoResistorData getPhotoResistorData() {
PhotoResistorData prData;
int analogValue = analogRead(PHOTORESISTOR_SENSOR_AO_PIN);
prData.voltage = analogValue / 1024. * 5;
prData.resistance = 2000 * prData.voltage / (1 - prData.voltage / 5);
prData.lux = pow(RL10 * 1e3 * pow(10, GAMMA) / prData.resistance, (1 / GAMMA));
return prData;
}
void dispLcd(PhotoResistorData data) {
static float last = 0;
if (data.lux == last) {
return;
} else {
last = data.lux;
}
ssd1306.clearDisplay();
ssd1306.setCursor(0, 0);
ssd1306.println("Photo Resistor Data.\n");
ssd1306.print("volt : ");
ssd1306.print(data.voltage, 1);
ssd1306.println(" v");
ssd1306.print("resist : ");
ssd1306.print(data.resistance, 1);
ssd1306.println(" ohm");
ssd1306.print("lux : ");
ssd1306.print(data.lux, 1);
ssd1306.println(" lux");
ssd1306.display();
}
void dispLed(PhotoResistorData data) {
static float last = 0;
if (data.lux == last) {
return;
} else {
last = data.lux;
}
//uint8_t level = map(data.lux, 0, 100916, 0, 10);
uint8_t level = map(data.voltage * 10, 50, 0, 0, 10);
ShiftResistorData srData = { 0 };
if (level) {
for (uint8_t i = 0; i < level; i++) {
srData.data_16 |= 0x0001 << i;
}
}
digitalWrite(SHIFT_RESISTOR_STCP_PIN, LOW);
for (int8_t i = (sizeof(srData) / sizeof(uint8_t)); i >= 0 ; i--) {
shiftOut(SHIFT_RESISTOR_DS_PIN, SHIFT_RESISTOR_SHCP_PIN, MSBFIRST, srData.data_8[i]);
}
digitalWrite(SHIFT_RESISTOR_STCP_PIN, HIGH);
}
void rotateServo(PhotoResistorData data) {
static uint8_t pos = 0;
static bool direction = true;
uint8_t level = map(data.voltage * 10, 50, 0, 1, 10);
if (direction) {
if (pos + level > 180) {
pos = 180;
direction = false;
} else {
pos += level;
}
} else {
if (pos - level < 0) {
pos = 0;
direction = true;
} else {
pos -= level;
}
}
servo.write(pos);
}