nxp/nxp3d/nxp3d.c

See examples/nxp/nxp3d

/*
* ZentriOS SDK LICENSE AGREEMENT | Zentri.com, 2015.
*
* Use of source code and/or libraries contained in the ZentriOS SDK is
* subject to the Zentri Operating System SDK license agreement and
* applicable open source license agreements.
*
* This app uses a Moray sensor backpack to stream accelerometer,
* temperature and humidity data to a webapp accessible via a softAP.
* Text is also scrolled across an 8x8 LED matrix on the backpack.
*
* The sensor backpack contains:
* - Accelerometer
* - Thermometer
* - Hygrometer
* - LED 8x8 display
* - 8 Mbyte serial flash
*
* INSTRUCTIONS FOR USE
* ----------------------------------------------------------------------
* 1. Run the app
*
* 2. Using a WLAN client (smartphone/PC/tablet), connect to the board using
* the following network credentials ...
* Name: Moray3D
* Password: password
*
* 3. Open a web browser and go to http://moray.3d
*
* 4. Pick up the board and watch the model move in real time in the browser
*
* 5. Use the prompt at the top left of the web page to change the
* scrolling text on the LED matrix
*
* 6. For added effect on a PC, use the scroll wheel to zoom the model
*
*/
#include "zos.h"
#include "sensor.h"
#include "accelerometer.h"
#include "thermometer.h"
#include "lcd.h"
#define ACCELEROMETER_READ_PERIOD 50 // ms
#define THERMOMETER_READ_PERIOD 1000 // ms
#define ACCELEROMETER_STREAM_NAME "accelerometer"
#define THERMOMETER_STREAM_NAME "thermometer"
#define DISPLAY_STREAM_NAME "display"
#define MAX_DISPLAY_CHARS 32
static const accelerometer_config_t const accel_config =
{
.samp_freq = ACCEL_SAMP_FREQ_100HZ,
.axis_en = ACCEL_AXIS_EN_X | ACCEL_AXIS_EN_Y | ACCEL_AXIS_EN_Z,
};
static zos_bool_t is_initialized;
/*************************************************************************************************/
void zn_app_init(void)
{
zos_result_t result;
ZOS_LOG("Starting NXP 3D Demo");
if(ZOS_FAILED(result, zn_load_app_settings("nxp3d.ini")))
{
ZOS_LOG("Failed to load app settings: %d", result);
return;
}
if (ZOS_FAILED(result, initialise_sensors()))
{
ZOS_LOG("Failed to initialise sensors");
return;
}
if (ZOS_FAILED(result, initialise_display()))
{
ZOS_LOG("Failed to initialise display!");
}
zn_hs_stream_register_callback(ACCELEROMETER_STREAM_NAME, accelerometer_stream_callback, NULL);
zn_hs_stream_register_callback(THERMOMETER_STREAM_NAME, thermometer_stream_callback, NULL);
zn_hs_stream_register_callback(DISPLAY_STREAM_NAME, display_stream_callback, NULL);
{
ZOS_LOG("Failed to restart network: %d", result);
}
else
{
{
ZOS_LOG("Failed to start the HTTP server!");
}
else
{
ZOS_LOG("Connect with a Wi-Fi client to: NXP-3D / password");
ZOS_LOG("Using a browser, go to http://nxp3d.com");
is_initialized = ZOS_TRUE;
}
}
}
/*************************************************************************************************/
void zn_app_deinit(void)
{
}
/*************************************************************************************************/
zos_bool_t zn_app_idle(void)
{
// return TRUE so the event loop idles
// it'll awake when the LED matrix needs to be updated or the HTTP server receives a request
return is_initialized;
}
/*************************************************************************************************/
static zos_result_t initialise_display(void)
{
lcd_init(); /* Initialize LCD Device and Turn it ON */
/* Draw a rectangle border */
lcd_draw_rect(0, 0, LCD_X_RES - 1, LCD_Y_RES - 1, 1);
lcd_draw_rect(1, 1, LCD_X_RES - 2, LCD_Y_RES - 2, 1);
/* Set foreground as ON */
lcd_set_background_color(0); /* Background is OFF */
lcd_put_str_centered("NXP 3D Demo!");
return ZOS_SUCCESS;
}
/*************************************************************************************************/
static zos_result_t initialise_sensors(void)
{
zos_result_t result;
if (ZOS_FAILED(result, sensor_init(SENSOR_ACCELEROMETER, (void*)&accel_config)))
{
ZOS_LOG("ERROR - Failed to initialize accelerometer!");
retval = result;
}
{
ZOS_LOG("ERROR - Failed to initialize thermometer!");
retval = result;
}
return retval;
}
/*************************************************************************************************/
static zos_result_t accelerometer_stream_callback(zos_hs_handle_t handle, const char *stream, zos_hs_stream_method_t method, void *arg)
{
if(method == HS_STREAM_LISTEN)
{
ZOS_LOG("Stream listener registered, streaming data");
zn_event_register_periodic(accelerometer_read_event_handler, handle, ACCELEROMETER_READ_PERIOD, EVENT_FLAGS1(RUN_NOW));
}
else if(method == HS_STREAM_UNLISTEN)
{
ZOS_LOG("Stream listener unregistered");
zn_event_unregister(accelerometer_read_event_handler, handle);
}
else if(method == HS_STREAM_READ)
{
char *update_interval_str;
if(zn_hs_stream_read(handle, &update_interval_str, NULL) == ZOS_SUCCESS)
{
uint32_t update_interval = str_to_uint32(update_interval_str);
zn_event_update_periodic(accelerometer_read_event_handler, handle, update_interval, EVENT_FLAGS1(RUN_NOW));
ZOS_LOG("Accelerometer update interval: %d", update_interval);
}
}
return ZOS_SUCCESS;
}
/*************************************************************************************************/
static zos_result_t thermometer_stream_callback(zos_hs_handle_t handle, const char *stream, zos_hs_stream_method_t method, void *arg)
{
if(method == HS_STREAM_LISTEN)
{
ZOS_LOG("Thermometer stream listener registered, streaming data");
zn_event_register_periodic(thermometer_read_event_handler, handle, THERMOMETER_READ_PERIOD, EVENT_FLAGS1(RUN_NOW));
}
else if(method == HS_STREAM_UNLISTEN)
{
ZOS_LOG("Thermometer stream listener unregistered");
zn_event_unregister(thermometer_read_event_handler, handle);
}
else if(method == HS_STREAM_READ)
{
char *update_interval_str;
if(zn_hs_stream_read(handle, &update_interval_str, NULL) == ZOS_SUCCESS)
{
uint32_t update_interval = str_to_uint32(update_interval_str);
zn_event_update_periodic(thermometer_read_event_handler, handle, update_interval, EVENT_FLAGS1(RUN_NOW));
ZOS_LOG("Thermometer update interval: %d", update_interval);
}
}
return ZOS_SUCCESS;
}
/*************************************************************************************************/
static zos_result_t display_stream_callback(zos_hs_handle_t handle, const char *stream, zos_hs_stream_method_t method, void *arg)
{
if(method == HS_STREAM_READ)
{
char* data;
uint16_t data_len;
if(zn_hs_stream_read(handle, &data, &data_len) == ZOS_SUCCESS)
{
// clear old text first
lcd_fill_rect(3, 3, LCD_X_RES-3, LCD_Y_RES-3, 0);
data[MIN(data_len, 12)] = 0;
ZOS_LOG("Display text updated");
}
}
return ZOS_SUCCESS;
}
/*************************************************************************************************/
static void accelerometer_read_event_handler(void *arg)
{
zos_result_t result;
if (ZOS_FAILED(result, get_sensor_data(SENSOR_ACCELEROMETER, &accel_data)))
{
ZOS_LOG("Failed to get accelerometer data!");
}
else
{
send_accel_data(handle, &accel_data);
}
}
/*************************************************************************************************/
static void thermometer_read_event_handler(void *arg)
{
thermometer_data_t thermometer_data;
zos_result_t result;
if (ZOS_FAILED(result, get_sensor_data(SENSOR_THERMOMETER, &thermometer_data)))
{
ZOS_LOG("Failed to get thermometer data!");
}
else
{
send_thermometer_data(handle, &thermometer_data);
}
}
/*************************************************************************************************/
static zos_result_t send_accel_data(const zos_hs_handle_t handle, accelerometer_data_t *data)
{
char buffer[64];
char *ptr = buffer;
ptr += sprintf(ptr, "{\"x\":%d,", (int)data->x);
ptr += sprintf(ptr, "\"y\":%d,", (int)data->y);
ptr += sprintf(ptr, "\"z\":%d}", (int)data->z);
return send_data(handle, ACCELEROMETER_STREAM_NAME, buffer);
}
/*************************************************************************************************/
static zos_result_t send_thermometer_data(const zos_hs_handle_t handle, thermometer_data_t *data)
{
char buffer[20];
sprintf(buffer, "{\"temp_c\":%d}", (int)data->raw);
return send_data(handle, THERMOMETER_STREAM_NAME, buffer);
}
/*************************************************************************************************/
static zos_result_t send_data(const zos_hs_handle_t handle, const char *stream, const char *data)
{
zos_buffer_t json_buffer =
{
.data = (uint8_t*)data,
.size = strlen(data)
};
// json encode the string in-place
json_encode_buffer(&json_buffer);
return zn_hs_stream_write_listener(handle, stream, data, ZOS_TRUE);
}
/*************************************************************************************************/
static zos_result_t get_sensor_data(sensor_id_t sensor, void* data)
{
zos_bool_t has_data = ZOS_FALSE;
if (sensor_has_new_data(sensor, &has_data) == ZOS_SUCCESS)
{
if (has_data == ZOS_TRUE)
{
if (sensor_get_data(sensor, data) != ZOS_SUCCESS)
{
ZOS_LOG("Failed to get data!");
}
else
{
result = ZOS_SUCCESS;
}
}
else
{
ZOS_LOG("No new data!");
result = ZOS_SUCCESS;
}
}
else
{
ZOS_LOG("Failed to check for new data!");
}
return result;
}