Skip to content

Instantly share code, notes, and snippets.

@IOT-123
Created May 12, 2018 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IOT-123/1d806aa3f8d0e74828055dc493948c7b to your computer and use it in GitHub Desktop.
Save IOT-123/1d806aa3f8d0e74828055dc493948c7b to your computer and use it in GitHub Desktop.
SCAFFOLDING FOR ASSIMILATE SENSOR USING ATTINY85
/*
*
* 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