Created
May 12, 2018 04:15
-
-
Save IOT-123/1d806aa3f8d0e74828055dc493948c7b to your computer and use it in GitHub Desktop.
SCAFFOLDING FOR ASSIMILATE SENSOR USING ATTINY85
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
/* | |
* | |
* IOT123 ATTINY85 I2C SLAVE AUTO-JOIN LAYER FOR SENSOR: XXX | |
* | |
* Take readings on XXX and send across wire on request via I2C in 3 segment 16byte packets | |
* ID of PROPERTY (set in _properties) | |
* VALUE of PROPERTY (set in getProperties) | |
* MORE TO COME (0/1 0 = last property) | |
* | |
* Pins on ATTINY85 | |
* SDA PB0 | |
* SCL PB2 | |
* XXX | |
*/ | |
#include <Wire.h> //SDA pin5/PB0, SCL pin7/PB2 | |
#define arraySize(x) (sizeof(x) / sizeof(x[0])) | |
#define NVC_NUM_STAGES 3 | |
//------------------------------SENSOR SPECIFIC DECLARATIONS | |
#define ADDRESS_SLAVE 10 | |
#define PIN_SENSOR A3 | |
//--------------------------END SENSOR SPECIFIC DECLARATIONS | |
#define TIME_RESPONSE_MS 0 // will be last value sent to master + padding | |
#if (TIME_RESPONSE_MS) | |
unsigned long startMillis; | |
#endif | |
struct nvc | |
{ | |
char Name[16]; | |
char Value[16]; | |
bool Continue; | |
}; | |
//------------------------------SENSOR SPECIFIC METADATA | |
nvc _metas[6] = { | |
{"AS_NAME", "TEMT6000", true}, | |
{"AS_VERSION", "1", true}, | |
{"POWER_DOWN", "1", true}, | |
{"PREPARES", "0", true}, | |
{"RESPONSE_MS", "70", true}, | |
{"VCC_MV", "", false} // ALWAYS HAVE THIS LAST | |
}; | |
//--------------------------END SENSOR SPECIFIC METADATA | |
//------------------------------SENSOR SPECIFIC PROPERTIES | |
nvc _props[3] ={ | |
{"Amb Illum (LUX)", "", true}, | |
{"Amb Illum (FC)", "", true},// Foot Candel units | |
{"Amb Irri (W/M2)", "", false},// Watt per Square Metre | |
}; | |
//--------------------------END SENSOR SPECIFIC PROPERTIES | |
volatile int _packetStage = 0; | |
volatile int _propertyIndex = 0; | |
volatile bool _metasConfirmed = false; | |
void setup() | |
{ | |
Wire.begin(ADDRESS_SLAVE); | |
Wire.onReceive(receiveEvent); | |
Wire.onRequest(requestEvent); | |
} | |
void loop() | |
{ | |
} | |
void receiveEvent (int howMany) | |
{ | |
byte buf[10]; | |
int i; | |
for (i=0; i<howMany; i++) | |
{ | |
buf[i] = Wire.read(); // receive byte as a character | |
} | |
if((buf[0] == 1) && (howMany == 1)){ | |
_metasConfirmed = true; | |
_packetStage = 0; | |
_propertyIndex = 0; | |
} | |
} | |
void requestEvent() { | |
char currentPacket[16]; | |
int propCount = 0; | |
if (_metasConfirmed){ | |
if (_propertyIndex == 0){ | |
// get the sensor properties | |
getProperties(); | |
} | |
strcpy(currentPacket, nvcAsCharArray(_props[_propertyIndex], _packetStage)); | |
propCount = arraySize(_props); | |
// get the metadata | |
}else{ | |
propCount = arraySize(_metas); | |
if ((propCount == _propertyIndex + 1) && (_packetStage == 1)){// if last metadata (VCC) | |
itoa(getVcc(), currentPacket, 10); | |
}else{ // just a normal metadata item | |
strcpy(currentPacket, nvcAsCharArray(_metas[_propertyIndex], _packetStage)); | |
} | |
} | |
Wire.write(currentPacket); // send metadate or sensor property | |
_packetStage = _packetStage + 1; | |
// go to next property if at last stage of current property | |
if (_packetStage == NVC_NUM_STAGES){ | |
_packetStage = 0; | |
_propertyIndex++; | |
} | |
// all properties processed? | |
if (_propertyIndex == propCount){ | |
_propertyIndex = 0; | |
// "0" should terminate requests to this slave | |
} | |
} | |
//------------------------------SENSOR SPECIFIC PROPERTY READING | |
void getProperties(){ | |
#if (TIME_RESPONSE_MS) | |
startMillis = millis(); | |
#endif | |
// float lux = analogRead(PIN_SENSOR) * RATIO_LUX; | |
// float ftCd = lux/10.764; | |
// float wattsm2 = lux/683.0; | |
// dtostrf(lux,5,3,_props[0].Value); | |
// dtostrf(ftCd,5,3,_props[1].Value); | |
// dtostrf(wattsm2,5,3,_props[2].Value); | |
} | |
//--------------------------END SENSOR SPECIFIC PROPERTY READING | |
char* nvcAsCharArray(nvc nvc, int packetStage){ | |
switch (packetStage){ | |
case 0: | |
return nvc.Name; | |
break; | |
case 1: | |
#if (TIME_RESPONSE_MS) | |
unsigned long currentMillis; | |
currentMillis = millis(); | |
char millis[16]; | |
itoa(currentMillis - startMillis, millis, 10); | |
return millis; | |
#endif | |
return nvc.Value; | |
break; | |
case 2: | |
return nvc.Continue ? "1" : "0"; | |
break; | |
default: | |
char result[16]; | |
itoa(packetStage, result, 10); | |
return result; | |
} | |
} | |
// https://www.avrfreaks.net/forum/attiny85-vcc-measurement-skews-higher-vcc-voltages | |
//5v = 6393, 6504 | |
//3.3V 3430 | |
uint16_t getVcc() { | |
// Read 1.1V reference against AVcc | |
// set the reference to Vcc and the measurement to the internal 1.1V reference | |
ADMUX = _BV(MUX3) | _BV(MUX2); | |
delay(2); // Wait for Vref to settle | |
uint16_t result = 0; | |
for (int x = 0; x < 32; x++){ | |
ADCSRA |= _BV(ADSC); // Start conversion | |
while (bit_is_set(ADCSRA,ADSC)); // measuring | |
if (x > 15){ | |
result += (int16_t)((int16_t)(ADC - result) / 2); | |
} | |
else{ | |
result = ADC; | |
} | |
} | |
uint16_t voltage = 1125300 / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 | |
return voltage; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment