UoK Shed IOT Crossing
Dependencies: EthernetInterface MQTT mbed-dsp mbed-rtos mbed
Fork of KL25Z_FFT_Demo_tony by
Revision 3:54760764be66, committed 2016-01-08
- Comitter:
- Condo2k4
- Date:
- Fri Jan 08 15:49:02 2016 +0000
- Parent:
- 2:aa24865dfef5
- Child:
- 4:59cf023f41d0
- Commit message:
- Initial import
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Fri Jan 08 15:49:02 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#2fc406e2553f
--- a/FastAnalogIn.lib Fri Jul 11 17:03:53 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/Sissors/code/FastAnalogIn/#a9b753c25073
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MQTT.lib Fri Jan 08 15:49:02 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/mqtt/code/MQTT/#e335fcc1a663
--- a/NVIC_set_all_priorities.lib Fri Jul 11 17:03:53 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/frankvnk/code/NVIC_set_all_priorities/#01504ecd2025
--- a/arm_const_structs.h Fri Jul 11 17:03:53 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010-2013 ARM Limited. All rights reserved. -* -* $Date: 17. January 2013 -* $Revision: V1.4.1 -* -* Project: CMSIS DSP Library -* Title: arm_const_structs.h -* -* Description: This file has constant structs that are initialized for -* user convenience. For example, some can be given as -* arguments to the arm_cfft_f32() function. -* -* Target Processor: Cortex-M4/Cortex-M3 -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* - Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* - Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* - Neither the name of ARM LIMITED nor the names of its contributors -* may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -------------------------------------------------------------------- */ - -#ifndef _ARM_CONST_STRUCTS_H -#define _ARM_CONST_STRUCTS_H - -#include "arm_math.h" -#include "arm_common_tables.h" - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = { - 16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE__16_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = { - 32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE__32_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = { - 64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE__64_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = { - 128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = { - 256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = { - 512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = { - 1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE1024_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = { - 2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE2048_TABLE_LENGTH - }; - - const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = { - 4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE4096_TABLE_LENGTH - }; - -#endif -
--- a/main.cpp Fri Jul 11 17:03:53 2014 +0000 +++ b/main.cpp Fri Jan 08 15:49:02 2016 +0000 @@ -4,363 +4,108 @@ // mods by Tony Abbey to simplify code to drive tri-colour LED as a "colour organ" #include "mbed.h" -#include "NVIC_set_all_priorities.h" -#include <ctype.h> -#include "arm_math.h" -#include "arm_const_structs.h" -#include "FastAnalogIn.h" -Serial pc(USBTX, USBRX); - -FastAnalogIn Audio(PTC2); - -// #define RGBW_ext // Disable this line when you want to use the KL25Z on-board RGB LED. - - -#ifndef RGBW_ext -// RGB direct output to PWM channels - on-board RGB LED - PwmOut gled(LED_GREEN); - PwmOut rled(LED_RED); - PwmOut bled(LED_BLUE); -#else - PwmOut gled(D6); - PwmOut rled(D5); - PwmOut bled(D7); - -#endif +#include "EthernetInterface.h" +#include "MQTTEthernet.h" +#include "MQTTClient.h" -// Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !! -// More info at https://mbed.org/questions/1387/How-can-I-access-the-FTFA_FOPT-register-/ -extern "C" void NMI_Handler() { - DigitalIn test(PTA4); -} - +#define IP_RETRIES 2 +#define HOSTNAME "192.168.0.1" +//#define HOSTNAME "doughnut.kent.ac.uk" +#define PORT 1883 -//////////////////////////////////////////////////////////////////////////////// -// CONFIGURATION -// These values can be changed to alter the behavior of the spectrum display. -// KL25Z limitations -// ----------------- -// - When used with the Spectrogram python script : -// There is a substantial time lag between the music and the screen output. -// Max allowed SAMPLE_RATE_HZ is 40000 -// Max allowed FFT_SIZE is 64 -//////////////////////////////////////////////////////////////////////////////// +enum Mode {RESPONCIVE, OVERRIDE}; -int SAMPLE_RATE_HZ = 8000; // Sample rate of the audio in hertz - note was 20000 -float SPECTRUM_MIN_DB = 33.0; // Audio intensity (in decibels) that maps to low LED brightness. -float SPECTRUM_MAX_DB = 60.0; // Audio intensity (in decibels) that maps to high LED brightness. -int LEDS_ENABLED = 1; // Control if the LED's should display the spectrum or not. 1 is true, 0 is false. - // Useful for turning the LED display on and off with commands from the serial port. -const int FFT_SIZE = 64; // Size of the FFT. -const int PIXEL_COUNT = 3; // Number of pixels (RGB LED). You should be able to increase this without - // any other changes to the program. -const int MAX_CHARS = 65; // Max size of the input command buffer -int PRINT_ON = 0; // flag to send chars continually to serial output +//buffers +char mqtt_buffer[100]; +MQTT::Message message; -//////////////////////////////////////////////////////////////////////////////// -// INTERNAL STATE -// These shouldn't be modified unless you know what you're doing. -//////////////////////////////////////////////////////////////////////////////// -const static arm_cfft_instance_f32 *S; -Ticker samplingTimer; -float samples[FFT_SIZE*2]; -float magnitudes[FFT_SIZE]; -int sampleCounter = 0; -char commandBuffer[MAX_CHARS]; -float frequencyWindow[PIXEL_COUNT+1]; -float hues[PIXEL_COUNT]; -float oldhues[PIXEL_COUNT]; -float huescount = 1; -bool commandRecv = 0; -//////////////////////////////////////////////////////////////////////////////// -// UTILITY FUNCTIONS -//////////////////////////////////////////////////////////////////////////////// - -void rxisr() { - char c = pc.getc(); - // Add any characters that aren't the end of a command (semicolon) to the input buffer. - if (c != ';') { - c = toupper(c); - strncat(commandBuffer, &c, 1); - } else { - // Parse the command because an end of command token was encountered. - commandRecv = 1; - } -} +//topics +char personTopic[] = "shed/masterclass/iot/crossing/person"; +char modeTopic[] = "shed/masterclass/iot/crossing/mode"; -// Compute the average magnitude of a target frequency window vs. all other frequencies. -void windowMean(float* magnitudes, int lowBin, int highBin, float* windowMean, float* otherMean) -{ - *windowMean = 0; - *otherMean = 0; - // Notice the first magnitude bin is skipped because it represents the - // average power of the signal. - for (int i = 1; i < FFT_SIZE/2; ++i) { - if (i >= lowBin && i <= highBin) { - *windowMean += magnitudes[i]; - } else { - *otherMean += magnitudes[i]; - } - } - *windowMean /= (highBin - lowBin) + 1; - *otherMean /= (FFT_SIZE / 2 - (highBin - lowBin)); -} +//io +AnalogIn sensor(A0); +DigitalOut GND(A2); +DigitalOut pelican(D0); +Ticker presenceTimer; -// Convert a frequency to the appropriate FFT bin it will fall within. -int frequencyToBin(float frequency) -{ - float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); - return int(frequency / binFrequency); -} - +//state +bool personPresent = false; +volatile Mode mode = RESPONCIVE; +volatile bool checkPresence = false; -//////////////////////////////////////////////////////////////////////////////// -// SPECTRUM DISPLAY FUNCTIONS -/////////////////////////////////////////////////////////////////////////////// - -void spectrumSetup() -{ - // Set the frequency window values by evenly dividing the possible frequency - // spectrum across the number of neo pixels. - float windowSize = (SAMPLE_RATE_HZ / 2.0) / float(PIXEL_COUNT); - for (int i = 0; i < PIXEL_COUNT+1; ++i) { - frequencyWindow[i] = i*windowSize; - } - +void presenceTick() { + checkPresence = true; } -void spectrumLoop() -{ - // Update each LED based on the intensity of the audio - // in the associated frequency window. - static int SLpixcnt = 0; - float intensity, otherMean; - int SLpixend = PIXEL_COUNT; - for (int i = SLpixcnt; i < SLpixend; ++i) { - windowMean(magnitudes, - frequencyToBin(frequencyWindow[i]), - frequencyToBin(frequencyWindow[i+1]), - &intensity, - &otherMean); - // Convert intensity to decibels. - intensity = 20.0*log10(intensity); - // Scale the intensity and clamp between 0 and 1.0. - intensity -= SPECTRUM_MIN_DB; - intensity = intensity < 0.0 ? 0.0 : intensity; - intensity /= (SPECTRUM_MAX_DB-SPECTRUM_MIN_DB); - //intensity = intensity > 1.0 ? 1.0 : intensity; - hues[i]=(intensity+oldhues[i]) / huescount; // averaging function - oldhues[i]=hues[i]; - huescount += 1; - if (huescount > 9) huescount = 1; - } - rled=1.0-hues[0] ; // onboard LED is common anode so inversion needed - gled=1.0-hues[1]; - bled=1.0-hues[2]; -} - - -//////////////////////////////////////////////////////////////////////////////// -// SAMPLING FUNCTIONS -//////////////////////////////////////////////////////////////////////////////// - -void samplingCallback() -{ - // Read from the ADC and store the sample data - samples[sampleCounter] = (1024 * Audio) - 511.0f; - // samples[sampleCounter] = Audio ; // just to see what this call actually produces - // Complex FFT functions require a coefficient for the imaginary part of the input. - // Since we only have real data, set this coefficient to zero. - samples[sampleCounter+1] = 0.0; - // Update sample buffer position and stop after the buffer is filled - sampleCounter += 2; - if (sampleCounter >= FFT_SIZE*2) { - samplingTimer.detach(); - } -} - -void samplingBegin() -{ - // Reset sample buffer position and start callback at necessary rate. - sampleCounter = 0; - samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); -} - -bool samplingIsDone() -{ - return sampleCounter >= FFT_SIZE*2; -} - - -//////////////////////////////////////////////////////////////////////////////// -// COMMAND PARSING FUNCTIONS -// These functions allow parsing simple commands input on the serial port. -// Commands allow reading and writing variables that control the device. -// -// All commands must end with a semicolon character. -// -// Example commands are: -// GET SAMPLE_RATE_HZ; -// - Get the sample rate of the device. -// SET SAMPLE_RATE_HZ 400; -// - Set the sample rate of the device to 400 hertz. -// -//////////////////////////////////////////////////////////////////////////////// - -void parseCommand(char* command) -{ - if (strcmp(command, "GET MAGNITUDES") == 0) { - for (int i = 1; i < FFT_SIZE; ++i) { - printf("%4.2f,", magnitudes[i]); - } - } else if (strcmp(command, "GET SAMPLES") == 0) { - for (int i = 0; i < FFT_SIZE*2; i+=2) { - printf("%f,", samples[i]); - } - } else if (strcmp(command, "GET FFT_SIZE") == 0) { - printf("%d\r\n", FFT_SIZE); - } else if (strcmp(command, "GET SAMPLE_RATE_HZ") == 0) { - printf("%d\r\n", SAMPLE_RATE_HZ); - } else if (strstr(command, "SET SAMPLE_RATE_HZ") != NULL) { - SAMPLE_RATE_HZ = (typeof(SAMPLE_RATE_HZ)) atof(command+(sizeof("SET SAMPLE_RATE_HZ")-1)); - } else if (strcmp(command, "GET LEDS_ENABLED") == 0) { - printf("%d\r\n", LEDS_ENABLED); - } else if (strstr(command, "SET LEDS_ENABLED") != NULL) { - LEDS_ENABLED = (typeof(LEDS_ENABLED)) atof(command+(sizeof("SET LEDS_ENABLED")-1)); - } else if (strcmp(command, "GET SPECTRUM_MIN_DB") == 0) { - printf("%f\r\n", SPECTRUM_MIN_DB); - } else if (strstr(command, "SET SPECTRUM_MIN_DB") != NULL) { - SPECTRUM_MIN_DB = (typeof(SPECTRUM_MIN_DB)) atof(command+(sizeof("SET SPECTRUM_MIN_DB")-1)); - } else if (strcmp(command, "GET SPECTRUM_MAX_DB") == 0) { - printf("%f\r\n", SPECTRUM_MAX_DB); - } else if (strstr(command, "SET SPECTRUM_MAX_DB") != NULL) { - SPECTRUM_MAX_DB = (typeof(SPECTRUM_MAX_DB)) atof(command+(sizeof("SET SPECTRUM_MAX_DB")-1)); - } else if (strcmp(command, "GET HUES") == 0) { - for (int i = 0; i < PIXEL_COUNT; ++i) { - printf("%f\r\n", hues[i]); - } - } else if (strcmp(command, "GET FREQUENCIES") == 0) { - for (int i = 0; i < PIXEL_COUNT; ++i) { - printf("%f\r\n", frequencyWindow[i]); - } - } else if (strcmp(command, "PRINT_ON") == 0) { - PRINT_ON = 1; - } else if (strcmp(command, "PRINT_OFF") == 0) { - PRINT_ON = 0; - } - // Update spectrum display values if sample rate was changed. - if (strstr(command, "SET SAMPLE_RATE_HZ ") != NULL) { - spectrumSetup(); - } - - - // Turn off the LEDs if the state changed. - if (LEDS_ENABLED == 0) { - } -} - -void parserLoop() -{ - // Process any incoming characters from the serial port - while (pc.readable()) { - char c = pc.getc(); - // (doesnt work!) printf("%c",c); // echo characters typed - // Add any characters that aren't the end of a command (semicolon) to the input buffer. - if (c != ';') { - c = toupper(c); - strncat(commandBuffer, &c, 1); - } else { - // Parse the command because an end of command token was encountered. - parseCommand(commandBuffer); - // Clear the input buffer - memset(commandBuffer, 0, sizeof(commandBuffer)); +void messageArrived(MQTT::MessageData& md) { + MQTT::Message &msg = md.message; + if(msg.payloadlen>0) { + switch(*(char*)msg.payload) { + case 'r': case 'R': mode = RESPONCIVE; pelican=personPresent; break; + case 'o': case 'O': mode = OVERRIDE; pelican=true; break; } } } -//////////////////////////////////////////////////////////////////////////////// -// MAIN FUNCTION -//////////////////////////////////////////////////////////////////////////////// - -int main() -{ - NVIC_set_all_irq_priorities(1); - NVIC_SetPriority(UART0_IRQn, 0); - // Set up serial port. - pc.baud (38400); - pc.attach(&rxisr); - - // Clear the input command buffer - memset(commandBuffer, 0, sizeof(commandBuffer)); - - // Initialize spectrum display - spectrumSetup(); - - // Begin sampling audio - samplingBegin(); +int main() { - // Init arm_ccft_32 - switch (FFT_SIZE) - { - case 16: - S = & arm_cfft_sR_f32_len16; - break; - case 32: - S = & arm_cfft_sR_f32_len32; - break; - case 64: - S = & arm_cfft_sR_f32_len64; - break; - case 128: - S = & arm_cfft_sR_f32_len128; - break; - case 256: - S = & arm_cfft_sR_f32_len256; - break; - case 512: - S = & arm_cfft_sR_f32_len512; - break; - case 1024: - S = & arm_cfft_sR_f32_len1024; - break; - case 2048: - S = & arm_cfft_sR_f32_len2048; - break; - case 4096: - S = & arm_cfft_sR_f32_len4096; - break; + MQTTEthernet ipstack; + MQTT::Client<MQTTEthernet, Countdown> m_client(ipstack); + + int ip_result; + for(int i=0; i<IP_RETRIES; i++) { + int ip_result = ipstack.connect(HOSTNAME, PORT); + if(ip_result==0) break; + } + if (ip_result != 0) { + error("IP stack failed"); + } + if(m_client.connect()!=MQTT::SUCCESS) { + error("MQTT connection failed"); + } + if(m_client.subscribe(modeTopic, MQTT::QOS0, messageArrived)!=MQTT::SUCCESS) { + error("MQTT subscribe failed"); } - + + GND = 0; //provide sensor with ground + + presenceTimer.attach_us(&presenceTick,50000); + while(1) { - // Calculate FFT if a full sample is available. - if (samplingIsDone()) { - // Run FFT on sample data. - arm_cfft_f32(S, samples, 0, 1); - // Calculate magnitude of complex numbers output by the FFT. - arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); - - if (LEDS_ENABLED == 1) { - spectrumLoop(); - } - wait_ms(10); - // Restart audio sampling. - samplingBegin(); - if (PRINT_ON == 1) { - for (int i = 0; i < PIXEL_COUNT; ++i) { - printf("%f\r\n", hues[i]); + + sleep(); + + if(checkPresence) { + float s = sensor; + if((s<0.5f)!=personPresent) { //state changed + if(personPresent) { + //last person left + personPresent = false; + } else { + //person arrived + personPresent = true; + } + + sprintf(mqtt_buffer, "{\"personPresent\":%d}", personPresent); + message.qos = MQTT::QOS0; // Send at least once + // Do not null terminate -- we have a length field, and it will piss off the JS front end + message.payloadlen = strlen(mqtt_buffer); + message.payload = (void*)mqtt_buffer; + m_client.publish(personTopic, message); + + if(mode==RESPONCIVE) { + pelican = personPresent; } } - } - - // Parse any pending commands. - if(commandRecv) { -// pc.attach(NULL); - parseCommand(commandBuffer); - commandRecv = 0; - // Clear the input buffer - memset(commandBuffer, 0, sizeof(commandBuffer)); -// pc.attach(&rxisr); + checkPresence = false; } + + m_client.yield(100); } -} + + + /* + */ +} \ No newline at end of file
--- a/mbed-dsp.lib Fri Jul 11 17:03:53 2014 +0000 +++ b/mbed-dsp.lib Fri Jan 08 15:49:02 2016 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/teams/mbed-official/code/mbed-dsp/#7a284390b0ce +https://mbed.org/teams/mbed-official/code/mbed-dsp/#e15125680ed7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Fri Jan 08 15:49:02 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#c825593ece39
--- a/mbed.bld Fri Jul 11 17:03:53 2014 +0000 +++ b/mbed.bld Fri Jan 08 15:49:02 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/4336505e4b1c \ No newline at end of file