Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2018 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "mbed.h"
00020 #include <stdio.h>
00021 #include <errno.h>
00022 
00023 #include "qspi_api.h"
00024 #include "QSPI.h"
00025 #include "qspi-blockdevice/QSPIFBlockDevice.h"
00026 #define DEVICE_QSPI
00027 
00028 #include "FATFileSystem.h"
00029 #include "LittleFileSystem.h"
00030 #include "simple-mbed-cloud-client.h"
00031 // #include "SDBlockDevice.h"
00032 #include "ISM43362Interface.h"
00033 // #include "SPIFBlockDevice.h" // to use onboard spi flash
00034 
00035 #define WIFI_SSID       "mbed"
00036 #define WIFI_PASSWORD   "workshop-password"
00037 
00038 
00039 
00040 #include "HTS221/HTS221Sensor.h"
00041 
00042 float rtime = 5.0;
00043 
00044 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
00045 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
00046 EventQueue eventQueue;
00047 
00048 // Declaring net interface as a global variable instead of local to avoid stack overflow
00049 ISM43362Interface net;
00050 
00051 // Storage implementation definition, currently using SDBlockDevice (SPI flash, DataFlash, and internal flash are also available)
00052 // SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS);
00053 QSPIFBlockDevice sd(PE_12, PE_13, PE_14, PE_15,PE_10,PE_11,0,8000000);
00054 
00055 // FATFileSystem fs("sd", &bd);
00056 
00057 LittleFileSystem fs("sd");
00058 
00059 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
00060 MbedCloudClientResource *button_res;
00061 MbedCloudClientResource *pattern_res;
00062 MbedCloudClientResource *temperature_res;
00063 MbedCloudClientResource *humidity_res;
00064 
00065 
00066 int SwipeCount = 0;
00067 InterruptIn PIR(D5);
00068 DigitalOut motorOnLed(LED4);
00069 DigitalOut PIRtrigger(LED2); 
00070 DigitalOut connectLED(LED1);
00071             
00072 Thread motorThread;
00073 Semaphore motorHold;
00074 
00075 void motorAction(void)
00076 {
00077 while(1) {
00078     motorHold.wait();
00079     SwipeCount++;
00080     motorOnLed = 0;
00081     PIRtrigger = 1;
00082     button_res->set_value(SwipeCount);
00083     wait(rtime);
00084     motorOnLed = 1;
00085     }
00086 }
00087     
00088 void PIRhandler(void)
00089 {
00090     motorHold.release();
00091 }
00092    
00093 void PIRreset(void)
00094 {
00095     PIRtrigger = 0;
00096 }
00097 
00098 
00099 // Manage the HST221 in an independent thread
00100 Thread HTS221Thread;
00101 
00102 void HTS221Handler(void)
00103 {
00104     uint8_t id;
00105     float value1, value2;
00106     static DevI2C devI2c(PB_11,PB_10); // This defines the processor port pins attached to the I2C bus
00107     static HTS221Sensor hum_temp(&devI2c);
00108 
00109     hum_temp.init(NULL);
00110     hum_temp.read_id(&id); // Read the device ID
00111     //printf("\r\n\n\nHTS221  humidity & temperature    = 0x%X\r\n", id);
00112     hum_temp.enable();
00113     while(5) {
00114         //printf("PIR=%x\r\n", PIR.read());
00115         wait(5); // Update every 5 seconds
00116         // Update temperature and humidity resources 
00117         hum_temp.get_temperature(&value1);
00118         hum_temp.get_humidity(&value2);
00119         temperature_res->set_value(value1);
00120         humidity_res->set_value(value2);
00121     }
00122 }
00123 
00124 
00125 // This function gets triggered by the timer. It's easy to replace it by an InterruptIn and fall() mode on a real button
00126 void fake_button_press() {
00127  //   int v = button_res->get_value_int() + 1;
00128 
00129 
00130     printf("Dispenser Swiped %d times\n", SwipeCount);
00131 }
00132 
00133 /**
00134  * PUT handler
00135  * @param resource The resource that triggered the callback
00136  * @param newValue Updated value for the resource
00137  */
00138 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
00139     //printf("PUT received, new value: %s\n", newValue.c_str());
00140     rtime = atof(newValue.c_str());
00141     printf("New Rtime= %f\r\n", rtime);
00142 }
00143 
00144 /**
00145  * POST handler
00146  * @param resource The resource that triggered the callback
00147  * @param buffer If a body was passed to the POST function, this contains the data.
00148  *               Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
00149  * @param size Size of the body
00150  */
00151 /*void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
00152     printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
00153 
00154     static DigitalOut augmentedLed(LED2); // LED that is used for blinking the pattern
00155 
00156     // Parse the pattern string, and toggle the LED in that pattern
00157     string s = std::string(pattern_res->get_value().c_str());
00158     //printf("Pattern = %s\r\n", s);
00159     size_t i = 0;
00160     size_t pos = s.find(':');
00161     while (pos != string::npos) {
00162         wait_ms(atoi(s.substr(i, pos - i).c_str()));
00163         augmentedLed = !augmentedLed;
00164 
00165         i = ++pos;
00166         pos = s.find(':', pos);
00167 
00168         if (pos == string::npos) {
00169             wait_ms(atoi(s.substr(i, s.length()).c_str()));
00170             augmentedLed = !augmentedLed;
00171         }
00172     }
00173 }
00174 */
00175 /**
00176  * Notification callback handler
00177  * @param resource The resource that triggered the callback
00178  * @param status The delivery status of the notification
00179  */
00180 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
00181     printf("callback %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00182 }
00183 /*
00184 void temperature_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
00185     printf("Temperature %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00186 }
00187 
00188 void humidity_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
00189     printf("Humidity %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00190 }
00191 */
00192 
00193 void startData(void)
00194 {
00195     connectLED = 1;
00196     PIR.rise(PIRhandler);
00197     PIR.fall(PIRreset);
00198     motorThread.start(motorAction);
00199     HTS221Thread.start(HTS221Handler);
00200 }
00201 
00202 /**
00203  * Registration callback handler
00204  * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
00205  */
00206 void registered(const ConnectorClientEndpointInfo *endpoint) {
00207     printf("Connected to Mbed Cloud. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
00208     startData(); 
00209 }
00210 
00211 int main(void) {
00212     connectLED = 0;
00213     motorOnLed = 1;
00214     printf("Starting Simple Mbed Cloud Client example\n");
00215 
00216     printf("Checking SDCard is Formatted\r\n");
00217     int err = fs.mount(&sd);
00218     printf("%s\n", (err ? "Fail :(" : "OK"));
00219     if (err) {
00220         // Reformat if we can't mount the filesystem
00221         // this should only happen on the first boot
00222         printf("No filesystem found, formatting... ");
00223         fflush(stdout);
00224         err = fs.reformat(&sd);
00225         printf("%s\n", (err ? "Fail :(" : "OK"));
00226         if (err) {
00227             error("error: %s (%d)\n", strerror(-err), err);
00228         }
00229     }
00230     // err = fs.unmount();
00231     // printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00232     // if (err < 0) {
00233     //     error("error: %s (%d)\n", strerror(-err), err);
00234     // }
00235 
00236     printf("Connecting to the network using Wifi...\n");
00237 
00238     // Connect to the internet (DHCP is expected to be on)
00239     nsapi_error_t status = net.connect(WIFI_SSID, WIFI_PASSWORD, (strlen(WIFI_PASSWORD) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);
00240 
00241     if (status != 0) {
00242         printf("Connecting to the network failed %d!\n", status);
00243         return -1;
00244     }
00245 
00246     printf("Connected to the network successfully. IP address: %s\n", net.get_ip_address());
00247 
00248     // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
00249     SimpleMbedCloudClient client(&net, &sd, &fs);
00250     int client_status = client.init();
00251     if (client_status != 0) {
00252         printf("Initializing Mbed Cloud Client failed (%d)\n", client_status);
00253         return -1;
00254     }
00255 
00256     // Creating resources, which can be written or read from the cloud
00257     button_res = client.create_resource("3200/0/5501", "button_count");
00258     button_res->set_value(0);
00259     button_res->methods(M2MMethod::GET);
00260     button_res->observable(true);
00261     button_res->attach_notification_callback(button_callback);
00262 
00263     pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
00264     pattern_res->set_value("5.0");
00265     pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
00266     pattern_res->attach_put_callback(pattern_updated);
00267 
00268 /*
00269     MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
00270     blink_res->methods(M2MMethod::POST);
00271     blink_res->attach_post_callback(blink_callback);
00272 */    
00273     temperature_res = client.create_resource("3303/0/5700", "temperature");
00274     temperature_res->set_value(0);
00275     temperature_res->methods(M2MMethod::GET);
00276     temperature_res->observable(true);
00277     temperature_res->attach_notification_callback(button_callback);
00278     
00279     humidity_res = client.create_resource("3304/0/5700", "humidity");
00280     humidity_res->set_value(0);
00281     humidity_res->methods(M2MMethod::GET);
00282     humidity_res->observable(true);
00283     humidity_res->attach_notification_callback(button_callback);
00284    
00285     printf("Initialized Mbed Cloud Client. Registering...\n");
00286 
00287     // Callback that fires when registering is complete
00288     client.on_registered(&registered);
00289 
00290     // Register with Mbed Cloud
00291     client.register_and_connect();
00292 
00293     // You can easily run the eventQueue in a separate thread if required
00294     eventQueue.dispatch_forever();
00295 }