Last active
January 7, 2018 23:17
-
-
Save IOT-123/b8c70fadd7fb2691908190a6ee1bf5dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* modified from code | |
* by Mathias Leroy | |
* | |
* V0.2 MODIFICATIONS | |
** I2C SET GET | |
** EEPROM SET GET | |
** REMOVE SERIAL OUTPUT - AFFECTED I2C | |
** ENABLE/DISABLE TRACKING | |
** MOVE SERVOS TO LIMITS VIA I2C | |
** READ CURRENT AVG INTENSITY VIA I2C | |
*/ | |
#include <Wire.h> | |
#include <stdio.h> | |
#include <Servo.h> | |
#include <EEPROM.h> | |
#define EEPROM_VERSION 0 | |
#define I2C_MSG_IN_SIZE 3 | |
#define PIN_LDR_TL A0 | |
#define PIN_LDR_TR A1 | |
#define PIN_LDR_BR A3 | |
#define PIN_LDR_BL A2 | |
#define CMD_IDX_HORI 0 // future functions | |
#define CMD_IDX_VERT 1 | |
#define CMD_VAL_MIN 0 | |
#define CMD_VAL_MAX 1 | |
#define IDX_I2C_ADDR 0 | |
#define IDX_V_ANGLE_INIT 1 | |
#define IDX_V_ANGLE_MIN 2 | |
#define IDX_V_ANGLE_MAX 3 | |
#define IDX_V_SENSITIVITY 4 | |
#define IDX_V_STEP 5 | |
#define IDX_H_ANGLE_INIT 6 | |
#define IDX_H_ANGLE_MIN 7 | |
#define IDX_H_ANGLE_MAX 8 | |
#define IDX_H_SENSITIVITY 9 | |
#define IDX_H_STEP 10 | |
#define IDX_WAKE_SECONDS 11 | |
#define IDX_SLEEP_MINUTES 12 | |
#define IDX_V_DAWN_ANGLE 13 | |
#define IDX_H_DAWN_ANGLE 14 | |
#define IDX_DAWN_INTENSITY 15 // average of all LDRS | |
#define IDX_DUSK_INTENSITY 16 // average of all LDRS | |
#define IDX_END_EEPROM_SET 17 | |
#define IDX_VOLTAGE 18 | |
#define IDX_TRACKER_ENABLED 19 | |
#define IDX_CURRENT_INTENSITY 20 // average of all LDRS - used for calculating IDX_DAWN_INTENSITY ambiant non-direct light | |
#define IDX_END_VALUES_GET 21 | |
#define IDX_SIGN_1 22 | |
#define IDX_SIGN_2 23 | |
#define IDX_SIGN_3 24 | |
Servo _servoH; | |
Servo _servoV; | |
byte _i2cVals[25] = {10, 90, 30, 150, 100, 5, 90, 0, 180, 100, 5, 30, 30, 40, 10, 30, 40, 0, 0, 1, 0, 0, 0, 0, 0}; | |
int _servoLoopDelay = 10; | |
int _slowingDelay=0; | |
int _angleH = 0; // set in setup from EEPROM | |
int _angleV = 0; // set in setup from EEPROM | |
int _averageTop = 0; | |
int _averageRight = 0; | |
int _averageBottom = 0; | |
int _averageLeft = 0; | |
byte _i2cResponse = 0; | |
void setup() | |
{ | |
getFromEeprom(); | |
_angleH = _i2cVals[IDX_H_ANGLE_INIT]; | |
_angleV = _i2cVals[IDX_V_ANGLE_INIT]; | |
Wire.begin(_i2cVals[IDX_I2C_ADDR]); | |
Wire.onReceive(receiveEvent); | |
Wire.onRequest(requestEvent); | |
_servoH.attach(5); | |
_servoH.write(_i2cVals[IDX_H_ANGLE_INIT]); | |
_servoV.attach(11); | |
_servoV.write(_i2cVals[IDX_V_ANGLE_INIT]); | |
} | |
void loop() | |
{ | |
getLightValues(); | |
moveServos(); | |
} | |
void getFromEeprom(){ | |
if( | |
EEPROM.read(IDX_SIGN_1) != 'S' || | |
EEPROM.read(IDX_SIGN_2) != 'T' || | |
EEPROM.read(IDX_SIGN_3) != EEPROM_VERSION | |
) EEPROM_write_default_configuration(); | |
EEPROM_read_configuration(); | |
} | |
void EEPROM_write_default_configuration(){ | |
for (int i = 0; i < IDX_END_EEPROM_SET; i++){ | |
EEPROM.update(i, _i2cVals[i]); | |
} | |
EEPROM.update(IDX_SIGN_1,'S'); | |
EEPROM.update(IDX_SIGN_2, 'T'); | |
EEPROM.update(IDX_SIGN_3, EEPROM_VERSION); | |
} | |
void EEPROM_read_configuration(){ | |
for (int i = 0; i < IDX_END_EEPROM_SET; i++){ | |
_i2cVals[i] = EEPROM.read(i); | |
} | |
} | |
void receiveEvent(int count) { | |
if (count == I2C_MSG_IN_SIZE) | |
{ | |
char cmd = Wire.read(); | |
byte index = Wire.read(); | |
byte value = Wire.read(); | |
switch (cmd) { | |
case 'E': | |
_i2cVals[IDX_TRACKER_ENABLED] = 1; | |
break; | |
case 'D': | |
_i2cVals[IDX_TRACKER_ENABLED] = 0; | |
break; | |
// case 'M': // future functions | |
// moveServoToLimit(index, value); | |
// break; | |
case 'G': | |
if (index < IDX_END_VALUES_GET){ | |
_i2cResponse = _i2cVals[index]; | |
} | |
break; | |
case 'S': | |
if (index < IDX_END_EEPROM_SET){ | |
_i2cVals[index] = value; | |
EEPROM.update(index, _i2cVals[index]); | |
} | |
break; | |
default: | |
return; | |
} | |
} | |
} | |
void requestEvent() | |
{ | |
Wire.write(_i2cResponse); | |
} | |
void getLightValues(){ | |
int valueTopLeft = analogRead(PIN_LDR_TL); | |
int valueTopRight = analogRead(PIN_LDR_TR); | |
int valueBottomRight = analogRead(PIN_LDR_BR); | |
int valueBottomLeft = analogRead(PIN_LDR_BL); | |
_averageTop = ( valueTopLeft + valueTopRight ) / 2; | |
_averageRight = ( valueTopRight + valueBottomRight ) / 2; | |
_averageBottom = ( valueBottomRight + valueBottomLeft ) / 2; | |
_averageLeft = ( valueBottomLeft + valueTopLeft ) / 2; | |
int avgIntensity = (valueTopLeft + valueTopRight + valueBottomRight + valueBottomLeft) / 4; | |
_i2cVals[IDX_CURRENT_INTENSITY] = map(avgIntensity, 0, 1024, 0, 255); | |
} | |
void moveServos(){ | |
if (_i2cVals[IDX_TRACKER_ENABLED] == 0) return; | |
if ( (_averageLeft-_averageRight)>_i2cVals[IDX_H_SENSITIVITY] && (_angleH-_i2cVals[IDX_H_STEP])>_i2cVals[IDX_H_ANGLE_MIN] ) { | |
// going left | |
delay(_slowingDelay); | |
for (int i=0; i < _i2cVals[IDX_H_STEP]; i++){ | |
_servoH.write(_angleH--); | |
delay(_servoLoopDelay); | |
} | |
} | |
else if ( (_averageRight-_averageLeft)>_i2cVals[IDX_H_SENSITIVITY] && (_angleH+_i2cVals[IDX_H_STEP])<_i2cVals[IDX_H_ANGLE_MAX] ) { | |
// going right | |
delay(_slowingDelay); | |
for (int i=0; i < _i2cVals[IDX_H_STEP]; i++){ | |
_servoH.write(_angleH++); | |
delay(_servoLoopDelay); | |
} | |
} | |
else { | |
// doing nothing | |
delay(_slowingDelay); | |
} | |
if ( (_averageTop-_averageBottom)>_i2cVals[IDX_V_SENSITIVITY] && (_angleV+_i2cVals[IDX_V_STEP])<_i2cVals[IDX_V_ANGLE_MAX] ) { | |
// going up | |
delay(_slowingDelay); | |
for (int i=0; i < _i2cVals[IDX_V_STEP]; i++){ | |
_servoV.write(_angleV++); | |
delay(_servoLoopDelay); | |
} | |
} | |
else if ( (_averageBottom-_averageTop)>_i2cVals[IDX_V_SENSITIVITY] && (_angleV-_i2cVals[IDX_V_STEP])>_i2cVals[IDX_V_ANGLE_MIN]) { | |
// going down | |
delay(_slowingDelay); | |
for (int i=0; i < _i2cVals[IDX_V_STEP]; i++){ | |
_servoV.write(_angleV--); | |
delay(_servoLoopDelay); | |
} | |
} | |
else { | |
delay(_slowingDelay); | |
} | |
} | |
void moveServoToLimit(byte servoIdx, byte limitVal){ | |
switch (servoIdx){ | |
case CMD_IDX_HORI: | |
switch (limitVal){ | |
case CMD_VAL_MIN: | |
_servoH.write(_i2cVals[IDX_H_ANGLE_MIN]); | |
break; | |
case CMD_VAL_MAX: | |
_servoH.write(_i2cVals[IDX_H_ANGLE_MAX]); | |
break; | |
default: | |
return; | |
} | |
break; | |
case CMD_IDX_VERT: | |
switch (limitVal){ | |
case CMD_VAL_MIN: | |
_servoV.write(_i2cVals[IDX_V_ANGLE_MIN]); | |
break; | |
case CMD_VAL_MAX: | |
_servoV.write(_i2cVals[IDX_V_ANGLE_MAX]); | |
break; | |
default: | |
return; | |
} | |
break; | |
default: | |
return; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment