STM32F103C8T6-Cayenne-WIZnet_SD1306_BMP280

Dependencies:   Cayenne-MQTT-mbed mbed Cayenne-WIZnet_Library WIZnet_Library BME280

main.cpp

Committer:
dadangjia
Date:
2019-11-08
Revision:
10:63b5e5d19bee
Parent:
9:3ba93660c82e

File content as of revision 10:63b5e5d19bee:

/**
* Example app for using the Cayenne MQTT C++ library to send and receive example data. This example uses
* the WIZnet_Library library to connect via Ethernet.
*
* NOTE: The WIZnet_Library defaults to using code for W5500. If you want to use a W5100 or W5200 code you need to 
* set the appropriate define in wiznet.h.
*/
#include "MQTTTimer.h"
#include "CayenneMQTTClient.h"
#include "MQTTNetwork.h"
#include "WIZnetInterface.h"
// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char* username = "c5495b90-ff04-11e6-a6b3-05972afbabc2";
char* password = "084cdefbc6a98c0b5b781716c9d102ce06b62cc4";
char* clientID = "267e1460-8aff-11e7-a5d9-9de9b49680ec";
#define USE_DHCP    1
                                                                                         
Serial pc(USBTX, USBRX);  //TX RX

SPI spi(D11, D12, D13);
WIZnetInterface ethernet(&spi, PB_0, PB_1); // SPI, SEL, Reset
MQTTNetwork<WIZnetInterface> network(ethernet);
CayenneMQTT::MQTTClient<MQTTNetwork<WIZnetInterface>, MQTTTimer> mqttClient(network, username, password, clientID);
char buffer[8][20];
float Temperature,Pressure;
long ADC_VALUE[3]; 
AnalogIn ADC_MQ2(A0);       //ADC1,MQ2空气质量检测
AnalogIn ADC_MQ3(A1);      //ADC2,MQ3空气质量检测
AnalogIn analog_value(A2); // ADC3,可调电位器
Ticker ticker; 
float tickerTime = 0.5; 
#include "CriusOLED.h"
void OLED_INIT()
{
    i2c.frequency(400000);
    init_OLED();
    displayOn();
    reset_display();
}

#include "BME280.h"
BME280 sensor(PB_9, PB_8);
void bme280_dat()
{
  Temperature=sensor.getTemperature();
  Pressure=sensor.getPressure()*100;
  snprintf(buffer[0],sizeof(buffer[0]), "%2.2fC %6.0fPa",Temperature, Pressure); 
  sendStrXY(buffer[0],0,0);  
}

//DigitalOut rled(PC_13);
//DigitalOut gled(PC_14);
//DigitalOut bled(PC_15);


#define ArrayLenth 25    //times of collection
#define Offset   0.00
float pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int   pHArrayIndex=0;
float pHValue;
Ticker ph_ticker; 
float  ph_sampleTime = 0.02;

void PH_ticker()
{
   pHArray[pHArrayIndex++]=analog_value.read(); 
   if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;	
}

void ph_dat()
{
 char i;
 float sum;
 for(i=0;i<ArrayLenth;i++)
   sum+=pHArray[pHArrayIndex];
   pHValue = (sum/ArrayLenth)*3.5*5.0+Offset;	
  snprintf(buffer[3],sizeof(buffer[3]), "pH:%2.2f",pHValue); 
  sendStrXY(buffer[3],3,0);     
}

void adc_dat()
{
  ADC_VALUE[0] = (long)(ADC_MQ2.read() * 3300); 
  ADC_VALUE[1] = (long)(ADC_MQ3.read() * 3300);
  ADC_VALUE[2] = (long)(analog_value.read() * 3300);
  snprintf(buffer[2],sizeof(buffer[2]), "%4dmV %4dmV",ADC_VALUE[0], ADC_VALUE[1]); 
  sendStrXY(buffer[2],2,0);  	
}

void Stm32f103c8t6_ticker()
{
 bme280_dat();
 adc_dat();
// ph_dat();
}
/**
* Print the message info.
* @param[in] message The message received from the Cayenne server.
*/
void outputMessage(CayenneMQTT::MessageData& message)
{
    size_t j;
    switch (message.topic)  {
    case COMMAND_TOPIC:
        pc.printf("topic=Command");
        break;
    case CONFIG_TOPIC:
        pc.printf("topic=Config");
        break;
    default:
        pc.printf("topic=%d", message.topic);
        break;
    }
    pc.printf(" channel=%d", message.channel);
    if (message.clientID) {
        pc.printf(" clientID=%s", message.clientID);
    }
    if (message.type) {
        pc.printf(" type=%s", message.type);
    }
    for (size_t i = 0; i < message.valueCount; ++i) {
		if (message.getValue(i)) {
			pc.printf(" value=%s", message.getValue(i));
			j = i;
		}
		if (message.getUnit(i)) {
			pc.printf(" unit=%s", message.getUnit(i));
		}
    }
    if (message.id) {
        pc.printf(" id=%s", message.id);
    }
    pc.printf("\n");
    /*
    switch(message.channel)
    {
    	case 7:if(strstr(message.getValue(j),"0"))
    	       {
    	       	 gled=0;
    	       }
               else if(strstr(message.getValue(j),"1"))
    	       {
    	       	 gled=1;
    	       } 
    	       pc.printf("LED=%s\n", message.getValue(j));   	       
    	break;
    	case 11:if(strstr(message.getValue(j),"0"))
    	       {
    	       	 bled=0;
    	       }
               else if(strstr(message.getValue(j),"1"))
    	       {
    	       	 bled=1;
    	       } 
    	       pc.printf("LED2=%s\n", message.getValue(j));   	       
    	break;    	
    }
    */    
   
}

/**
* Handle messages received from the Cayenne server.
* @param[in] message The message received from the Cayenne server.
*/
void messageArrived(CayenneMQTT::MessageData& message)
{
    int error = 0;
    // Add code to process the message. Here we just ouput the message data.
    outputMessage(message);

	if (message.topic == COMMAND_TOPIC) {
		// If this is a command message we publish a response to show we recieved it. Here we are just sending a default 'OK' response.
		// An error response should be sent if there are issues processing the message.
		if ((error = mqttClient.publishResponse(message.id, NULL, message.clientID)) != CAYENNE_SUCCESS) {
			pc.printf("Response failure, error: %d\n", error);
		}
			
		// Send the updated state for the channel so it is reflected in the Cayenne dashboard. If a command is successfully processed
		// the updated state will usually just be the value received in the command message.
		if ((error = mqttClient.publishData(DATA_TOPIC, message.channel, NULL, NULL, message.getValue())) != CAYENNE_SUCCESS) {
			pc.printf("Publish state failure, error: %d\n", error);
		}
	}
}

/**
* Connect to the Cayenne server.
* @return Returns CAYENNE_SUCCESS if the connection succeeds, or an error code otherwise.
*/
int connectClient(void)
{
    int error = 0;
    // Connect to the server.
    pc.printf("Connecting to %s:%d\n", CAYENNE_DOMAIN, CAYENNE_PORT);
    while ((error = network.connect(CAYENNE_DOMAIN, CAYENNE_PORT)) != 0) {
        pc.printf("TCP connect failed, error: %d\n", error);
        wait(2);
    }

    if ((error = mqttClient.connect()) != MQTT::SUCCESS) {
        pc.printf("MQTT connect failed, error: %d\n", error);
        return error;
    }
    pc.printf("Connected\n");

    // Subscribe to required topics.
    if ((error = mqttClient.subscribe(COMMAND_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
        pc.printf("Subscription to Command topic failed, error: %d\n", error);
    }
    if ((error = mqttClient.subscribe(CONFIG_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
        pc.printf("Subscription to Config topic failed, error:%d\n", error);
    }

    // Send device info. Here we just send some example values for the system info. These should be changed to use actual system data, or removed if not needed.
    mqttClient.publishData(SYS_VERSION_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, CAYENNE_VERSION);
    mqttClient.publishData(SYS_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "mbedDevice");
    mqttClient.publishData(SYS_CPU_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "CPU Model");
    mqttClient.publishData(SYS_CPU_SPEED_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "72000000");

    return CAYENNE_SUCCESS;
}

/**
* Main loop where MQTT code is run.
*/
void loop(void)
{
    // Start the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
    MQTTTimer timer(5000);

    while (true) {
        // Yield to allow MQTT message processing.
        mqttClient.yield(1000);

        // Check that we are still connected, if not, reconnect.
        if (!network.connected() || !mqttClient.connected()) {
            network.disconnect();
            mqttClient.disconnect();
            pc.printf("Reconnecting\n");
            while (connectClient() != CAYENNE_SUCCESS) {
                wait(2);
                pc.printf("Reconnect failed, retrying\n");
            }
        }

        // Publish some example data every few seconds. This should be changed to send your actual data to Cayenne.
        if (timer.expired()) {
            int error=0;
            if ((error = mqttClient.publishData(DATA_TOPIC, 0, TYPE_TEMPERATURE, UNIT_CELSIUS, Temperature)) != CAYENNE_SUCCESS) {
                pc.printf("T:%2.2fC\n",Temperature);
            }
            if ((error = mqttClient.publishData(DATA_TOPIC, 1, TYPE_LUMINOSITY, UNIT_LUX, (long)Pressure)) != CAYENNE_SUCCESS) {
                pc.printf("P:%6.0fPa\n",Pressure);
            }            
            if ((error = mqttClient.publishData(DATA_TOPIC, 8, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, ADC_VALUE[0])) != CAYENNE_SUCCESS) {
                pc.printf("A0:%4dmV\n", ADC_VALUE[0]);
            }
            if ((error = mqttClient.publishData(DATA_TOPIC, 9, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, ADC_VALUE[1])) != CAYENNE_SUCCESS) {
                pc.printf("A1:%4dmV\n", ADC_VALUE[1]);
            }
            if ((error = mqttClient.publishData(DATA_TOPIC, 10, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, ADC_VALUE[2])) != CAYENNE_SUCCESS) {
                pc.printf("A2:%4dmV\n", ADC_VALUE[2]);
            }
 //           if ((error = mqttClient.publishData(DATA_TOPIC, 13, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, pHValue)) != CAYENNE_SUCCESS) {
 //               pc.printf("PH:%.2f\n",pHValue);
 //           }                                                                                 
            // Restart the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
            timer.countdown_ms(5000);
        }
    }
}

char * IP_Addr    = "192.168.0.194";
char * IP_Subnet  = "255.255.255.0";
char * IP_Gateway = "192.168.0.1";
unsigned char MAC_Addr[6] = {0x00,0x08,0xDC,0x12,0x34,0x56};
void W5500_init()
{
        #if USE_DHCP
        int ret = ethernet.init(MAC_Addr);
        #else
        int ret = ethernet.init(MAC_Addr,IP_Addr,IP_Subnet,IP_Gateway);
        #endif
        if (!ret) {
            pc.printf("Initialized, MAC: %s\r\n", ethernet.getMACAddress());
            ret = ethernet.connect();
            if (!ret) {
                pc.printf("IP: %s, MASK: %s, GW: %s\r\n",
                          ethernet.getIPAddress(), ethernet.getNetworkMask(), ethernet.getGateway()); 
                sendStrXY("IP:",1,0); 
                sendStrXY(ethernet.getIPAddress(),1,3);                                   
            } else {
                pc.printf("Error ethernet.connect() - ret = %d\r\n", ret);
                exit(0);
            }
        } else {
            pc.printf("Error ethernet.init() - ret = %d\r\n", ret);
            exit(0);
        }       
}
/**
* Main function.
*/
int main()
{
    pc.baud(921600);
    pc.printf("Stm32f103k3t6-w5500-Cayeme-ethernet\n");
    OLED_INIT();
    ticker.attach(&Stm32f103c8t6_ticker, tickerTime); 
//    ph_ticker.attach(&PH_ticker, ph_sampleTime);  
    // Set the correct SPI frequency for your shield, if necessary. For example, 42000000 for Arduino Ethernet Shield W5500 or 20000000 for Arduino Ethernet Shield W5100.
    W5500_init();
    // Set the default function that receives Cayenne messages.
    mqttClient.setDefaultMessageHandler(messageArrived);
    // Connect to Cayenne.
    if (connectClient() == CAYENNE_SUCCESS) {
        // Run main loop.
        loop();
    }
    else {
        pc.printf("Connection failed, exiting\n");
    }

    if (mqttClient.connected())
        mqttClient.disconnect();
    if (network.connected())
        network.disconnect();

    return 0;
}