Genial!! Podrias pasarme el codigo fuente aplicado??
El código lo publicaré en breve, quiero hacer una guía porque no ha sido facil. el Attiny85 lo programo usando Arduino siguiendo esta guía
High-Low Tech ? Programming an ATtiny w/ Arduino 0022 Luego para programar el PCduino he usado varias apis entre ellas CURL y JSON-c para enviar los datos al servidor desde PCDuino, donde recojo los valores de cada sensor. La comunicación entre el Attiny85 y PCDuino en este momento la hago mediante un puerto seria, en el futuro quiero hacerlo mediante bluetooth serie que me permite que los sensores y el pcduino no estén en la misma habitación.
El código para programar en C el PCduino lo pillé de aquí:
https://github.com/pcduino/c_enviroment
Y el código fuente de la parte de pcduino se compone de dos partes:
El growbox:
/*
* I/O test program for a10
*/
#include <time.h>
#include <stdio.h>
#include <curl/curl.h>
#include <math.h>
#include <json.h>
#include <stdlib.h>
#include "timer/Timer.h"
#include "timer/Timer.cpp"
#include "timer/Event.h"
#include "timer/Event.cpp"
void postJSON(int lights, double temperature, double humidity, long photoValue);
void logString(char* string);
void append(char* s, char c);
int readDHT(int pin);
int readTiny();
void minuteProcess();
void quarterProcess();
#include <core.h>
#include "Serial.h"
int lights_pin = 7;
int fan_pin = 6;
double temperature;
double humidity;
long photoValue;
int lightsValue = 0;
int fanCounter = 0;
//#define DEBUG
CURL *curl;
CURLcode res;
json_object *cfg;
Timer minuteTimer;
Timer quarterTimer;
/* In windows, this will init the winsock stuff */
void setup() {
if (argc != 2) {
printf("Usage %s <configfile.conf>\n", argv[0]);
exit(-1);
}
printf("Starting Growbox controller\n");
/**********************
* CURL
*/
curl_global_init(CURL_GLOBAL_ALL);
//digitalWrite(lights_pin, LOW); // turn off LED
pinMode(lights_pin, OUTPUT);
pinMode(fan_pin, OUTPUT);
digitalWrite(fan_pin, LOW); // turn off FAN
int rate = 9600;
Serial.begin(rate);
minuteTimer.every(60 * 1000, minuteProcess);
quarterTimer.every(15 * 60 * 1000, quarterProcess);
// wait until NTP set the time.
delay(20000);
minuteProcess();
quarterProcess();
}
/**
* Process executed every minute
*/
void minuteProcess() {
cfg = json_object_from_file(argv[1]);
int startHour = 21, endHour = 15;
json_object *startHourObj = json_object_object_get(cfg, "startHour");
startHour = json_object_get_int(startHourObj);
json_object *endHourObj = json_object_object_get(cfg, "endHour");
endHour = json_object_get_int(endHourObj);
time_t rawtime;
struct tm * timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
char tempDate[200];
strftime(buffer, 80, "%H", timeinfo);
strftime(tempDate, 200, "%H:%M", timeinfo);
int hour = atoi(buffer);
char timeString[200];
sprintf(timeString, "Parsed Time: %s\n", tempDate);
logString(timeString);
// printf("Start Hour: %d\n", startHour);
// printf("End Hour: %d\n", endHour);
// consider here starting at night and ends and day
int lightsOn = 0;
if (startHour > endHour) {
// starts at the end of the day ends at the beggining.
if (hour >= startHour || hour < endHour) {
lightsOn = 1;
} else {
lightsOn = 0;
}
} else {
if (startHour >= hour && hour < endHour) {
lightsOn = 1;
} else {
lightsOn = 0;
}
}
if (lightsOn == 0) {
logString("LIGHTS: OFF\n");
digitalWrite(lights_pin, LOW); // turn off LED
lightsValue = 0;
} else {
digitalWrite(lights_pin, HIGH); // turn ON LED
logString("LIGHTS: ON\n");
lightsValue = 1;
}
logString("Fan: ON\n");
digitalWrite(fan_pin, HIGH); // turn on FAN
delay(45000);
digitalWrite(fan_pin, LOW); // turn off FAN
/**
* FAN START UP
*/
}
/**
* Quarter hour process.
*/
void quarterProcess() {
int resultDHT = 0;
int count = 0;
while (resultDHT == 0 /*&& count < 20*/) {
count++;
resultDHT = readTiny();
if (resultDHT == 0) {
logString("Error reading DHT\n");
delay(3000);
}
}
postJSON(lightsValue, temperature, humidity, photoValue);
}
void loop() {
minuteTimer.update();
quarterTimer.update();
delay(10);
/* Read the file. If there is an error, report it and exit. */
}
int readTiny() {
logString("Reading tiny\n");
//delay(2000);
int status;
char jsonString[500];
int i;
for (i = 0; i < 500; i++)
jsonString
= '\0';
FILE *fp;
/* Open the command for reading. */
fp = popen("/pcduino/target/serial", "r");
if (fp == NULL ) {
printf("Failed to run command\n");
}
/* Read the output a line at a time - output it. */
fgets(jsonString, sizeof(jsonString) - 1, fp);
/* close */
pclose(fp);
if (strlen(jsonString) > 0) {
json_object *jsonObj = json_tokener_parse(jsonString);
json_object *tempObj = json_object_object_get(jsonObj, "t");
temperature = json_object_get_double(tempObj);
json_object *humidObj = json_object_object_get(jsonObj, "h");
humidity = json_object_get_double(humidObj);
json_object *photoObj = json_object_object_get(jsonObj, "p");
photoValue = (long) json_object_get_int(photoObj);
// Map the value.
photoValue = map(photoValue, 0, 1023, 0, 100);
char data[200];
sprintf(data, "Temperature: %f, Humidity: %f, Photocell: %ld\n",
temperature, humidity, photoValue);
logString(data);
return 1;
} else {
logString("Error reading\n");
}
return 0;
}
void logString(char* string) {
FILE *file;
file = fopen("/var/log/growbox.log", "a+"); /* apend file (add text to
a file or create a file if it does not exist.*/
fprintf(file, "%s", string); /*writes*/
printf("%s", string); /*shows in console*/
fclose(file); /*done!*/
}
void append(char* s, char c) {
int len = strlen(s);
s[len] = c;
s[len + 1] = '\0';
}
/**
* Post the json call
*/
void postJSON(int lights, double temperature, double humidity, long photoValue) {
/* get a curl handle */
curl = curl_easy_init();
if (curl) {
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
curl_easy_setopt(curl, CURLOPT_URL,
"http://192.168.1.150:9080/controller/rest/state");
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
char jsonObj[200];
sprintf(jsonObj,
"{\"lights\" : %d, \"temperature\" : %f, \"humidity\" : %f, \"luminosity\" : %ld}",
lights, temperature, humidity, photoValue);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonObj);
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
}
y el programa para leer el attiny, que va por libre:
int readTiny();
#include <core.h>
#include "Serial.h"
int temperature = 0;
int humidity = 0;
int photoValue = 0;
char jsonString[500];
void setup() {
//Initialize serial and wait for port to open:
int rate = 9600;
Serial.begin(rate);
// prints title with ending line break
}
// first visible ASCIIcharacter '!' is number 33:
int thisByte = 33;
void loop() {
int result = 0;
int counter = 0;
while (result == 0 /*&& counter < 3*/) {
result = readTiny();
if (serialEventRun)
serialEventRun();
if (result == 0) {
counter++;
delay(3000);
}
}
exit(0);
}
int readTiny() {
int thisByte = 0;
//delay(2000);
int i = 0;
for (i = 0; i < 500; i++) {
jsonString = '\0';
}
char newChar[1];
Serial.write('r');
delay(500);
while (Serial.available() > 0) {
// read the incoming byte:
thisByte = Serial.read();
sprintf(newChar, "%c", thisByte);
strcat(jsonString, newChar);
// say what you got:
//Serial.println(thisByte, DEC);
//Serial.println(thisByte, OCT);
delay(10);
}
if (strlen(jsonString) > 0) {
printf("%s", jsonString);
return 1;
}
return 0;
}
Luego en el Attiny, el código es este:
#include <dht.h>
#include <SoftwareSerial.h>
const int rx=2;
const int tx=1;
const int dhtPin=0;
//const int led=1;
const int photocell=3;
dht DHT;
SoftwareSerial mySerial(rx, tx);
int temp;
int humidity;
void setup()
{
pinMode(rx,INPUT);
pinMode(tx,OUTPUT);
pinMode(photocell,INPUT);
mySerial.begin(9600);
}
void loop()
{
mySerial.println("Loop");
if (mySerial.available() > 0) {
mySerial.println("received");
mySerial.read();
int chk = -1;
do
{
chk = DHT.read22(dhtPin);
mySerial.print("Value:");
mySerial.println(chk);
if (chk != DHTLIB_OK) {
delay(3000);
}
}
while (chk != DHTLIB_OK);
mySerial.print("starting parse");
int photoValue = analogRead(photocell);
mySerial.print("{\"p\": ");
mySerial.print(photoValue);
mySerial.print(", ");
mySerial.print("\"t\": ");
mySerial.print(DHT.temperature, 1);
mySerial.print(", \"h\": ");
mySerial.print(DHT.humidity, 1);
mySerial.println("}");
} else {
mySerial.print("No data");
}
//mySerial.println("Finished");
delay(5000);
}//LOOP
Espero que te sirva, montarlo del todo es un poco complicado, luego tengo una aplicación Java que es la que realmente recoje los valores del sensor, los guarda en una base de datos y los muestra en el navegador. La publicaré en breve
Un saludo