My code:
Code: Select all
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Added new functionality based on the ChibiOS demo. Ben & Edwin alias DisruptiveNL
Clean Code principles used:
- Use Intention-Revealing Names
An I2C file to address all I2C definitions and functionality at one place
(c) 2017 DisruptiveNL
For: NUCLEO-STMF411RE
This c-file is representing the mailboxes. The readSensorX(chpi) functions are getting the values
and post them in a struct into the mailbox msgs
TODO: reading the respons from the ESP8266 (Serial) status 200!
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ch.h>
#include "hal.h"
#include "cffchipcap.h"
#include "chprintf.h"
#include "moistsensor.h"
#include "pwmds.h"
#include "esp8266.h"
/**
* In *.h
typedef struct
{
char *state;
char *url;
} DSMessage;
*
*/
//#define _DEBUG_
typedef enum {FILLED, NOTFILLED, SETUP,SETTINGUP,UNINITIALIZED,INITIALIZED,READY,SENDING,RESEND
,SENDINGHUM, SENDINGTEMP, SENDINGMOIST, SENDINGDC} esp_state_t;
bool state = false;
#define NUM_MSGS 16
#define _DEBUG_
#define _NOTSLEEP_
static esp_state_t esp_state = UNINITIALIZED;
static msg_t msgs_queue[NUM_MSGS];
static mailbox_t msgs;
static msg_t current_message;
static BaseSequentialStream *chpi;
/* USART config ESP8266 interface #1 */
static const SerialConfig esp8266uartcfg = {
115200,
0,
0,
0
};
/* The thread continuous which is fetching a message */
static THD_WORKING_AREA(waGETMESSAGEFROMMB, 512);
static THD_FUNCTION(GETMESSAGEFROMMB, arg)
{
(void)arg;
chRegSetThreadName("GETMESSAGE");
while(true) {
//The ampersand & symbol should be read as "the address of..". The star *
//symbol should be read as "the contents of the address...".
/* Waiting for a message.*/
if (chMBFetch(&msgs, (msg_t *)¤t_message, TIME_INFINITE)== MSG_OK)
{
chprintf((BaseSequentialStream*)&SD6,"espmicro.setData('%s','%d')\r\n",((DSMessage *)current_message)->url,((DSMessage *)current_message)->state);
}
else{
chprintf((BaseSequentialStream*)&SD6,"print('Mailbox empty!')\r\n");
chThdSleepMilliseconds(100);
}
chThdYield();
}
}
/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */
static THD_WORKING_AREA(waPOSTMESSAGETOMBTEMP, 512);
static THD_FUNCTION(POSTMESSAGETOMBTEMP, arg)
{
(void)arg;
chRegSetThreadName("GETMESSAGEFROMSENSORTEMP");
#ifndef _SLEEP_
systime_t time = chVTGetSystemTimeX();
#endif
while(true) {
#ifndef _SLEEP_
time += S2ST(60);
#endif
/*reading sensors like PWM, I2C and ADC*/
readSensor(chpi);
// cffchipcap.c
int32_t temp = getTemperatureValue();
DSMessage dsmi = {};
dsmi.state = temp;
dsmi.url = TEMPURL;
chMBPost(&msgs, (msg_t) &dsmi, TIME_INFINITE);
#ifndef _SLEEP_
chThdSleepUntil(time);
#else
chThdSleepSeconds(1);
#endif
}
}
/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */
static THD_WORKING_AREA(waPOSTMESSAGETOMBHUM, 512);
static THD_FUNCTION(POSTMESSAGETOMBHUM, arg)
{
(void)arg;
chRegSetThreadName("GETMESSAGEFROMSENSORHUM");
#ifndef _SLEEP_
systime_t time = chVTGetSystemTimeX();
#endif
while(true) {
#ifndef _SLEEP_
time += S2ST(70);
#endif
//readSensor(chpi); //Only do this at the sensor who is read the most often... else locking problems..
int32_t hum = getHumidityValue();
DSMessage dsm = {};
dsm.state = hum;
dsm.url = HUMURL;
chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
#ifndef _SLEEP_
chThdSleepUntil(time);
#else
chThdSleepSeconds(1);
#endif
}
}
/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */
static THD_WORKING_AREA(waPOSTMESSAGETOMBPWM, 512);
static THD_FUNCTION(POSTMESSAGETOMBPWM, arg)
{
(void)arg;
chRegSetThreadName("GETMESSAGEFROMSENSORPWM");
#ifndef _SLEEP_
systime_t time = chVTGetSystemTimeX();
#endif
while(true) {
#ifndef _SLEEP_
time += S2ST(80);
#endif
//readSensor(chpi);
int32_t pwm = getDutycycleValue();
DSMessage dsm = {};
dsm.state = pwm;
dsm.url = PWMURL;
chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
#ifndef _SLEEP_
chThdSleepUntil(time);
#else
chThdSleepSeconds(1);
#endif
//Let the main thread kick the PWM
setDPmwDs(pwm);
}
}
/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */
static THD_WORKING_AREA(waPOSTMESSAGETOMBMOIST, 512);
static THD_FUNCTION(POSTMESSAGETOMBMOIST, arg)
{
(void)arg;
chRegSetThreadName("GETMESSAGEFROMSENSORMOIST");
#ifndef _SLEEP_
systime_t time = chVTGetSystemTimeX();
#endif
int8_t counter = 0;
while(true) {
#ifndef _SLEEP_
time += S2ST(90);
#endif
readMoistSensor(chpi);
int32_t moist = getMoistValue();
DSMessage dsm = {};
dsm.state = moist;
dsm.url = MOISTURL;
/* So the ESP8266 does not get >3 sensor values the first time */
if (counter==1)
{
chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
}
#ifndef _SLEEP_
chThdSleepUntil(time);
#else
chThdSleepSeconds(1);
#endif
counter = 1;
}
}
////////////////////////////////////////
// ESP8266 UART Class Methods
////////////////////////////////////////
void initESP8266(BaseSequentialStream *chp)
{
/* start USART */
sdStart(&SD6, &esp8266uartcfg);
chprintf(chp, "Started SD6 ESP8266\r\n");
/* config GPIO on Nucleo */
palSetPadMode(stm32F411TxPort6, stm32F411TxPin6, PAL_MODE_ALTERNATE(8));
palSetPadMode(stm32F411RxPort6, stm32F411RxPin6, PAL_MODE_ALTERNATE(8));
chprintf(chp, "Init Pins ESP8266\r\n");
chThdSleepMilliseconds(500);
/* Make BaseSequentialStream sort of global */
chpi = chp;
chprintf(chp, "Init ESP8266 over USART \r\n");
/* Init mailboxes */
chMBObjectInit(&msgs, msgs_queue, NUM_MSGS);
/* Pre-filling the free buffers pool with the available buffers, the post
will not stop because the mailbox is large enough.*/
/* Init ESP8266 through USART */
chprintf((BaseSequentialStream*)&SD6,"import network\n\r");
chThdSleepMilliseconds(1000);
chprintf((BaseSequentialStream*)&SD6,"import config\n\r");
chThdSleepMilliseconds(1000);
chprintf((BaseSequentialStream*)&SD6,"import micropython\n\r");
chThdSleepMilliseconds(1000);
chprintf((BaseSequentialStream*)&SD6,"import espmicro\n\r");
chThdSleepMilliseconds(1000);
chprintf((BaseSequentialStream*)&SD6,"espmicro.do_connect()\n\r");
chThdSleepMilliseconds(1000);
chprintf((BaseSequentialStream*)&SD6,"network.WLAN(network.STA_IF).isconnected()\n\r");
chThdSleepMilliseconds(1000);
chprintf(chp, "\n\r");
chprintf(chp, "InitPool ESP8266 over USART \r\n");
esp_state = SETUP;
/* Start threads to run infinitive */
chThdCreateStatic(waGETMESSAGEFROMMB, sizeof(waGETMESSAGEFROMMB), NORMALPRIO, GETMESSAGEFROMMB, NULL);
chThdCreateStatic(waPOSTMESSAGETOMBTEMP, sizeof(waPOSTMESSAGETOMBTEMP), NORMALPRIO, POSTMESSAGETOMBTEMP, NULL);
chThdCreateStatic(waPOSTMESSAGETOMBHUM, sizeof(waPOSTMESSAGETOMBHUM), NORMALPRIO, POSTMESSAGETOMBHUM, NULL);
chThdCreateStatic(waPOSTMESSAGETOMBPWM, sizeof(waPOSTMESSAGETOMBPWM), NORMALPRIO, POSTMESSAGETOMBPWM, NULL);
chThdCreateStatic(waPOSTMESSAGETOMBMOIST, sizeof(waPOSTMESSAGETOMBMOIST), NORMALPRIO, POSTMESSAGETOMBMOIST, NULL);
chprintf(chp, "Functions ESP8266 over USART \r\n");
chprintf(chpi, "ESP status GETMESSAGE |: %d", esp_state);
chprintf(chpi, "\r\n");
}