diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 6f0dae26..f02f1acc 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -121,6 +121,7 @@ add_executable (hm11-example hm11.cxx) add_executable (ht9170-example ht9170.cxx) add_executable (h3lis331dl-example h3lis331dl.cxx) add_executable (ad8232-example ad8232.cxx) +add_executable (grovescam-example grovescam.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -220,6 +221,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/hm11) include_directories (${PROJECT_SOURCE_DIR}/src/ht9170) include_directories (${PROJECT_SOURCE_DIR}/src/h3lis331dl) include_directories (${PROJECT_SOURCE_DIR}/src/ad8232) +include_directories (${PROJECT_SOURCE_DIR}/src/grovescam) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -342,3 +344,4 @@ target_link_libraries (hm11-example hm11 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ht9170-example ht9170 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (h3lis331dl-example h3lis331dl ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ad8232-example ad8232 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (grovescam-example grovescam ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/grovescam.cxx b/examples/c++/grovescam.cxx new file mode 100644 index 00000000..6edd85d7 --- /dev/null +++ b/examples/c++/grovescam.cxx @@ -0,0 +1,77 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "grovescam.h" + +using namespace std; +using namespace upm; + +int main (int argc, char **argv) +{ +//! [Interesting] + + // Instantiate a Grove Serial Camera on UART 0 + upm::GROVESCAM* camera = new upm::GROVESCAM(0); + + // make sure port is initialized properly. 115200 baud is the default. + if (!camera->setupTty()) + { + cerr << "Failed to setup tty port parameters" << endl; + return 1; + } + + if (camera->init()) + cout << "Initialized..." << endl; + else + cout << "init() failed" << endl; + + if (camera->preCapture()) + cout << "preCapture succeeded..." << endl; + else + cout << "preCapture failed." << endl; + + if (camera->doCapture()) + cout << "doCapture succeeded..." << endl; + else + cout << "doCapture failed." << endl; + + cout << "Image size is " << camera->getImageSize() << " bytes" << endl; + + if (camera->getImageSize() > 0) + { + cout << "Storing image.jpg..." << endl; + if (camera->storeImage("image.jpg")) + cout << "storeImage succeeded..." << endl; + else + cout << "storeImage failed." << endl; + } +//! [Interesting] + + delete camera; + return 0; +} diff --git a/examples/javascript/grovescam.js b/examples/javascript/grovescam.js new file mode 100644 index 00000000..7872bf89 --- /dev/null +++ b/examples/javascript/grovescam.js @@ -0,0 +1,72 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +var cameraObj = require('jsupm_grovescam'); + +// Instantiate a Grove Serial Camera on UART 0 +var camera = new cameraObj.GROVESCAM(0); + +// make sure port is initialized properly. 115200 baud is the default. +if (!camera.setupTty()) +{ + console.log("Failed to setup tty port parameters"); + process.exit(1); +} + +if (camera.init()) + console.log("Initialized..."); +else + console.log("init() failed"); + +if (camera.preCapture()) + console.log("preCapture succeeded..."); +else + console.log("preCapture failed."); + +if (camera.doCapture()) + console.log("doCapture succeeded..."); +else + console.log("doCapture failed."); + +console.log("Image size is " + camera.getImageSize() + " bytes"); + +if (camera.getImageSize() > 0) +{ + console.log("Storing image.jpg..."); + if (camera.storeImage("image.jpg")) + console.log("storeImage succeeded..."); + else + console.log("storeImage failed."); +} + + +camera = null; +cameraObj.cleanUp(); +cameraObj = null; +console.log("Exiting."); +process.exit(0); + diff --git a/examples/python/grovescam.py b/examples/python/grovescam.py new file mode 100644 index 00000000..53ede097 --- /dev/null +++ b/examples/python/grovescam.py @@ -0,0 +1,61 @@ +#!/usr/bin/python +# +# Author: Jon Trulson +# Copyright (c) 2015 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import sys +import pyupm_grovescam as upmGrovescam + +# Instantiate a Grove Serial Camera on UART 0 +camera = upmGrovescam.GROVESCAM(0) + +# make sure port is initialized properly. 115200 baud is the default. +if (not camera.setupTty()): + print "Failed to setup tty port parameters" + sys.exit(1) + +if (camera.init()): + print "Initialized..." +else: + print "init() failed" + +if (camera.preCapture()): + print "preCapture succeeded..." +else: + print "preCapture failed." + +if (camera.doCapture()): + print "doCapture succeeded..." +else: + print "doCapture failed." + +print "Image size is", camera.getImageSize(), "bytes" + +if (camera.getImageSize() > 0): + print "Storing image.jpg..." + if (camera.storeImage("image.jpg")): + print "storeImage succeeded..." + else: + print "storeImage failed." + +print "Exiting." +sys.exit(0) diff --git a/src/grovescam/CMakeLists.txt b/src/grovescam/CMakeLists.txt new file mode 100644 index 00000000..509a6644 --- /dev/null +++ b/src/grovescam/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "grovescam") +set (libdescription "upm grove serial camera module") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/grovescam/grovescam.cxx b/src/grovescam/grovescam.cxx new file mode 100644 index 00000000..828fbf46 --- /dev/null +++ b/src/grovescam/grovescam.cxx @@ -0,0 +1,475 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "grovescam.h" + +using namespace upm; +using namespace std; + +static const int maxRetries = 100; + +GROVESCAM::GROVESCAM(int uart, uint8_t camAddr) +{ + m_ttyFd = -1; + + // save our shifted camera address, we'll need it a lot + m_camAddr = (camAddr << 5); + + m_picTotalLen = 0; + + if ( !(m_uart = mraa_uart_init(uart)) ) + { + cerr << __FUNCTION__ << ": mraa_uart_init() failed" << endl; + return; + } + + // This requires a recent MRAA (1/2015) + char *devPath = mraa_uart_get_dev_path(m_uart); + + if (!devPath) + { + cerr << __FUNCTION__ << ": mraa_uart_get_dev_path() failed" << endl; + return; + } + + // now open the tty + if ( (m_ttyFd = open(devPath, O_RDWR)) == -1) + { + cerr << __FUNCTION__ << ": open of " << devPath << " failed: " + << strerror(errno) << endl; + return; + } +} + +GROVESCAM::~GROVESCAM() +{ + if (m_ttyFd != -1) + close(m_ttyFd); +} + +bool GROVESCAM::dataAvailable(unsigned int millis) +{ + if (m_ttyFd == -1) + return false; + + struct timeval timeout; + + if (millis == 0) + { + // no waiting + timeout.tv_sec = 0; + timeout.tv_usec = 0; + } + else + { + timeout.tv_sec = millis / 1000; + timeout.tv_usec = (millis % 1000) * 1000; + } + + int nfds; + fd_set readfds; + + FD_ZERO(&readfds); + + FD_SET(m_ttyFd, &readfds); + + if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0) + return true; // data is ready + else + return false; +} + +int GROVESCAM::readData(uint8_t *buffer, size_t len) +{ + if (m_ttyFd == -1) + return(-1); + + int rv = read(m_ttyFd, (char *)buffer, len); + + if (rv < 0) + cerr << __FUNCTION__ << ": read failed: " << strerror(errno) << endl; + + return rv; +} + +int GROVESCAM::writeData(uint8_t *buffer, size_t len) +{ + if (m_ttyFd == -1) + return(-1); + + // first, flush any pending but unread input + + tcflush(m_ttyFd, TCIFLUSH); + + int rv = write(m_ttyFd, (char *)buffer, len); + + if (rv < 0) + { + cerr << __FUNCTION__ << ": write failed: " << strerror(errno) << endl; + return rv; + } + + tcdrain(m_ttyFd); + + return rv; +} + +bool GROVESCAM::setupTty(speed_t baud) +{ + if (m_ttyFd == -1) + return(false); + + struct termios termio; + + // get current modes + tcgetattr(m_ttyFd, &termio); + + // setup for a 'raw' mode. 81N, no echo or special character + // handling, such as flow control. + cfmakeraw(&termio); + + // set our baud rates + cfsetispeed(&termio, baud); + cfsetospeed(&termio, baud); + + // make it so + if (tcsetattr(m_ttyFd, TCSAFLUSH, &termio) < 0) + { + cerr << __FUNCTION__ << ": tcsetattr failed: " << strerror(errno) << endl; + return false; + } + + return true; +} + +void GROVESCAM::drainInput() +{ + uint8_t ch; + + while (dataAvailable(0)) + readData(&ch, 1); +} + +bool GROVESCAM::init() +{ + const unsigned int pktLen = 6; + uint8_t cmd[pktLen] = {0xaa, 0x0d|m_camAddr, 0x00, 0x00, 0x00, 0x00}; + uint8_t resp[pktLen]; + int retries = 0; + + while (true) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": retries exceeded" << endl; + return false; + } + + writeData(cmd, pktLen); + + if (!dataAvailable(500)) + continue; + + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0e | m_camAddr) + && resp[2] == 0x0d + && resp[4] == 0 + && resp[5] == 0) + { + if (readData(resp, pktLen) != pktLen) + continue; + else + { + if (resp[0] == 0xaa + && resp[1] == (0x0d | m_camAddr) + && resp[2] == 0 + && resp[3] == 0 + && resp[4] == 0 + && resp[5] == 0) + break; + } + } + } + + cmd[1] = 0x0e | m_camAddr; + cmd[2] = 0x0d; + writeData(cmd, pktLen); + + return true; +} + +bool GROVESCAM::preCapture(PIC_FORMATS_T fmt) +{ + const unsigned int pktLen = 6; + uint8_t cmd[pktLen] = { 0xaa, 0x01 | m_camAddr, 0x00, 0x07, 0x00, fmt }; + uint8_t resp[pktLen]; + int retries = 0; + + while (true) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": retries exceeded" << endl; + return false; + } + + drainInput(); + + writeData(cmd, pktLen); + + if (!dataAvailable(100)) + continue; + + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0e | m_camAddr) + && resp[2] == 0x01 + && resp[4] == 0 + && resp[5] == 0) break; + } + + return true; +} + +bool GROVESCAM::doCapture() +{ + const unsigned int pktLen = 6; + uint8_t cmd[pktLen] = { 0xaa, 0x06 | m_camAddr, 0x08, MAX_PKT_LEN & 0xff, + (MAX_PKT_LEN >> 8) & 0xff, 0}; + uint8_t resp[pktLen]; + int retries = 0; + + m_picTotalLen = 0; + + while (true) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": retries exceeded" << endl; + return false; + } + + drainInput(); + writeData(cmd, pktLen); + usleep(100000); + + if (!dataAvailable(100)) + continue; + + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0e | m_camAddr) + && resp[2] == 0x06 + && resp[4] == 0 + && resp[5] == 0) + break; + } + + cmd[1] = 0x05 | m_camAddr; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + cmd[5] = 0; + + retries = 0; + while (true) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": retries exceeded" << endl; + return false; + } + + drainInput(); + writeData(cmd, pktLen); + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0e | m_camAddr) + && resp[2] == 0x05 + && resp[4] == 0 + && resp[5] == 0) + break; + } + + cmd[1] = 0x04 | m_camAddr; + cmd[2] = 0x01; + + retries = 0; + while (true) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": retries exceeded" << endl; + return false; + } + + drainInput(); + writeData(cmd, 6); + + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0e | m_camAddr) + && resp[2] == 0x04 + && resp[4] == 0 + && resp[5] == 0) + { + if (!dataAvailable(1000)) + continue; + + if (readData(resp, pktLen) != pktLen) + continue; + + if (resp[0] == 0xaa + && resp[1] == (0x0a | m_camAddr) + && resp[2] == 0x01) + { + m_picTotalLen = (resp[3]) | (resp[4] << 8) | (resp[5] << 16); + break; + } + } + } + + return true; +} + +bool GROVESCAM::storeImage(char *fname) +{ + if (!fname) + { + cerr << __FUNCTION__ << "@" << __LINE__ + << ": fname is NULL" << endl; + return false; + } + + if (!m_picTotalLen) + { + cerr << __FUNCTION__ << "@" << __LINE__ + << ": Picture length is zero, you need to capture first." << endl; + + return false; + } + + FILE *file = fopen(fname, "wb"); + + if (!file) + { + cerr << __FUNCTION__ << "@" << __LINE__ + << ": fopen failed: " << strerror(errno) << endl; + + return false; + } + + /// let the games begin... + const unsigned int pktLen = 6; + unsigned int pktCnt = (m_picTotalLen) / (MAX_PKT_LEN - 6); + if ((m_picTotalLen % (MAX_PKT_LEN-6)) != 0) + pktCnt += 1; + + uint8_t cmd[pktLen] = { 0xaa, 0x0e | m_camAddr, 0x00, 0x00, 0x00, 0x00 }; + uint8_t pkt[MAX_PKT_LEN]; + int retries = 0; + bool failed = false; + + for (unsigned int i = 0; i < pktCnt; i++) + { + cmd[4] = i & 0xff; + cmd[5] = (i >> 8) & 0xff; + + retries = 0; + + retry: + + usleep(10000); + + drainInput(); + writeData(cmd, pktLen); + + if (!dataAvailable(1000)) + { + if (retries++ > maxRetries) + { + cerr << __FUNCTION__ << ": timeout, max retries exhausted." + << endl; + failed = true; + break; + } + goto retry; + } + + uint16_t cnt = readData(pkt, MAX_PKT_LEN); + + unsigned char sum = 0; + for (int y = 0; y < cnt - 2; y++) + { + sum += pkt[y]; + } + if (sum != pkt[cnt-2]) + { + if (retries++ <= maxRetries) + goto retry; + else + { + cerr << __FUNCTION__ << ": cksum error, max retries exhausted." + << endl; + failed = true; + break; + } + } + + fwrite((const uint8_t *)&pkt[4], cnt - 6, 1, file); + } + + cmd[4] = 0xf0; + cmd[5] = 0xf0; + writeData(cmd, pktLen); + + fclose(file); + + // reset the pic length to 0 for another run. + m_picTotalLen = 0; + + if (failed) + { + cerr << "Failed to download and store image." << endl; + return false; + } + + return true; +} diff --git a/src/grovescam/grovescam.h b/src/grovescam/grovescam.h new file mode 100644 index 00000000..2a2e28e7 --- /dev/null +++ b/src/grovescam/grovescam.h @@ -0,0 +1,194 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GROVESCAM_DEFAULT_UART 0 + +#define GROVESCAM_DEFAULT_CAMERA_ADDR 0 + +namespace upm { + /** + * @brief UPM library for the Grove Serial Camera + * @defgroup grovescam libupm-grovescam + * @ingroup seeed serial + */ + + /** + * @library grovescam + * @sensor grovescam + * @comname Grove Serial Camera + * @category other + * @manufacturer seeed + * @connection uart + * @web http://www.seeedstudio.com/wiki/Grove_-_Serial_Camera_Kit + * + * @brief C++ API for the Grove Serial Camera + * + * The driver was tested with the Grove Serial Camera. There is + * no protocol documentation currently available, so this module + * was developed based completely on the Seeed Studio Arduino + * sketch. + * + * It is connected via a UART at 115200 baud. + * + * @snippet grovescam.cxx Interesting + */ + + class GROVESCAM { + public: + + static const unsigned int MAX_PKT_LEN = 128; + + typedef enum { + FORMAT_VGA = 7, // 640x480 + FORMAT_CIF = 5, // 352×288 + FORMAT_OCIF = 3 // ??? (maybe they meant QCIF?) + } PIC_FORMATS_T; + + /** + * GROVESCAM module constructor + * + * @param uart default uart to use (0 or 1) + * @param camAddr the 3-bit address identifier of the camera, default 0 + */ + GROVESCAM(int uart, uint8_t camAddr=GROVESCAM_DEFAULT_CAMERA_ADDR); + + /** + * GROVESCAM module Destructor + */ + ~GROVESCAM(); + + /** + * check to see if there is data available for reading + * + * @param millis number of milliseconds to wait, 0 means no wait. + * @return true if there is data available to be read + */ + bool dataAvailable(unsigned int millis); + + /** + * read any available data into a user-supplied buffer. Note, the + * call will block until data is available to be read. Use + * dataAvailable() to determine whether there is data available + * beforehand, to avoid blocking. + * + * @param buffer the buffer to hold the data read + * @param len the length of the buffer + * @return the number of bytes read + */ + int readData(uint8_t *buffer, size_t len); + + /** + * write the data in buffer to the device + * + * @param buffer the buffer to hold the data read + * @param len the length of the buffer + * @return the number of bytes written + */ + int writeData(uint8_t *buffer, size_t len); + + /** + * setup the proper tty i/o modes and the baudrate. The default + * baud rate is 9600 (B9600) for this device. + * + * @param baud the desired baud rate. + * @return true if successful + */ + bool setupTty(speed_t baud=B115200); + + /** + * read serial input and discard until no more characters are available + * + */ + void drainInput(); + + /** + * initialize the camera + * + */ + bool init(); + + /** + * tell camera to prepare for a capture + * + * @param fmt one of the PIC_FORMATS_T values + */ + bool preCapture(PIC_FORMATS_T fmt=FORMAT_VGA); + + /** + * start the capture + * + * @return true if successful + */ + bool doCapture(); + + /** + * store the captured image in a file + * + * @param fname the name of the file to write + * @return true if successful + */ + bool storeImage(char *fname); + + /** + * return the picture length. Note, this is only valid after + * doCapture() has run successfully. + * + * @return the image length + */ + int getImageSize() { return m_picTotalLen; }; + + protected: + int ttyFd() { return m_ttyFd; }; + int setTtyFd(int fd) { m_ttyFd = fd; }; + + private: + mraa_uart_context m_uart; + int m_ttyFd; + + uint8_t m_camAddr; + int m_picTotalLen; + }; +} + + diff --git a/src/grovescam/jsupm_grovescam.i b/src/grovescam/jsupm_grovescam.i new file mode 100644 index 00000000..d8e12ec0 --- /dev/null +++ b/src/grovescam/jsupm_grovescam.i @@ -0,0 +1,8 @@ +%module jsupm_grovescam +%include "../upm.i" + +%{ + #include "grovescam.h" +%} + +%include "grovescam.h" diff --git a/src/grovescam/pyupm_grovescam.i b/src/grovescam/pyupm_grovescam.i new file mode 100644 index 00000000..83f9258a --- /dev/null +++ b/src/grovescam/pyupm_grovescam.i @@ -0,0 +1,9 @@ +%module pyupm_grovescam +%include "../upm.i" + +%feature("autodoc", "3"); + +%{ + #include "grovescam.h" +%} +%include "grovescam.h"