MPU6050のサンプルプログラム2
Dependencies: ConfigFile SDFileSystem mbed
Fork of LAURUS_program by
Revision 6:2b68f85a984a, committed 2015-06-12
- Comitter:
- onaka
- Date:
- Fri Jun 12 04:00:23 2015 +0000
- Parent:
- 5:182f6356bce1
- Child:
- 7:0ec343d29641
- Child:
- 8:602865d8fca3
- Commit message:
- logger update
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial/Buffer/Buffer.cpp Fri Jun 12 04:00:23 2015 +0000 @@ -0,0 +1,76 @@ + +/** + * @file Buffer.cpp + * @brief Software Buffer - Templated Ring Buffer for most data types + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Buffer.h" + +template <class T> +Buffer<T>::Buffer(uint32_t size) +{ + _buf = new T [size]; + _size = size; + clear(); + + return; +} + +template <class T> +Buffer<T>::~Buffer() +{ + delete [] _buf; + + return; +} + +template <class T> +uint32_t Buffer<T>::getSize() +{ + return this->_size; +} + +template <class T> +void Buffer<T>::clear(void) +{ + _wloc = 0; + _rloc = 0; + memset(_buf, 0, _size); + + return; +} + +template <class T> +uint32_t Buffer<T>::peek(char c) +{ + return 1; +} + +// make the linker aware of some possible types +template class Buffer<uint8_t>; +template class Buffer<int8_t>; +template class Buffer<uint16_t>; +template class Buffer<int16_t>; +template class Buffer<uint32_t>; +template class Buffer<int32_t>; +template class Buffer<uint64_t>; +template class Buffer<int64_t>; +template class Buffer<char>; +template class Buffer<wchar_t>;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial/Buffer/Buffer.h Fri Jun 12 04:00:23 2015 +0000 @@ -0,0 +1,167 @@ + +/** + * @file Buffer.h + * @brief Software Buffer - Templated Ring Buffer for most data types + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUFFER_H +#define BUFFER_H + +#include <stdint.h> +#include <string.h> + +/** A templated software ring buffer + * + * Example: + * @code + * #include "mbed.h" + * #include "Buffer.h" + * + * Buffer <char> buf; + * + * int main() + * { + * buf = 'a'; + * buf.put('b'); + * char *head = buf.head(); + * puts(head); + * + * char whats_in_there[2] = {0}; + * int pos = 0; + * + * while(buf.available()) + * { + * whats_in_there[pos++] = buf; + * } + * printf("%c %c\n", whats_in_there[0], whats_in_there[1]); + * buf.clear(); + * error("done\n\n\n"); + * } + * @endcode + */ + +template <typename T> +class Buffer +{ +private: + T *_buf; + volatile uint32_t _wloc; + volatile uint32_t _rloc; + uint32_t _size; + +public: + /** Create a Buffer and allocate memory for it + * @param size The size of the buffer + */ + Buffer(uint32_t size = 0x100); + + /** Get the size of the ring buffer + * @return the size of the ring buffer + */ + uint32_t getSize(); + + /** Destry a Buffer and release it's allocated memory + */ + ~Buffer(); + + /** Add a data element into the buffer + * @param data Something to add to the buffer + */ + void put(T data); + + /** Remove a data element from the buffer + * @return Pull the oldest element from the buffer + */ + T get(void); + + /** Get the address to the head of the buffer + * @return The address of element 0 in the buffer + */ + T *head(void); + + /** Reset the buffer to 0. Useful if using head() to parse packeted data + */ + void clear(void); + + /** Determine if anything is readable in the buffer + * @return 1 if something can be read, 0 otherwise + */ + uint32_t available(void); + + /** Overloaded operator for writing to the buffer + * @param data Something to put in the buffer + * @return + */ + Buffer &operator= (T data) + { + put(data); + return *this; + } + + /** Overloaded operator for reading from the buffer + * @return Pull the oldest element from the buffer + */ + operator int(void) + { + return get(); + } + + uint32_t peek(char c); + +}; + +template <class T> +inline void Buffer<T>::put(T data) +{ + _buf[_wloc++] = data; + _wloc %= (_size-1); + if(_wloc==_rloc){ + _rloc++; + _rloc %= (_size-1); + } + + return; +} + +template <class T> +inline T Buffer<T>::get(void) +{ + T data_pos = _buf[_rloc++]; + _rloc %= (_size-1); + + return data_pos; +} + +template <class T> +inline T *Buffer<T>::head(void) +{ + T *data_pos = &_buf[0]; + + return data_pos; +} + +template <class T> +inline uint32_t Buffer<T>::available(void) +{ + return (_wloc == _rloc) ? 0 : 1; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial/BufferedSerial.cpp Fri Jun 12 04:00:23 2015 +0000 @@ -0,0 +1,165 @@ +/** + * @file BufferedSerial.cpp + * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BufferedSerial.h" +#include <stdarg.h> + +BufferedSerial::BufferedSerial(PinName tx, PinName rx, PinName cts, uint32_t buf_size, uint32_t tx_multiple, const char* name) + : SERIAL_BASE(tx, rx) , _cts(cts), _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size)) +{ + SERIAL_BASE::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq); + this->_buf_size = buf_size; + this->_tx_multiple = tx_multiple; + + _cts.fall(this, &BufferedSerial::ctsInterrupt); + return; +} + +BufferedSerial::~BufferedSerial(void) +{ + SERIAL_BASE::attach(NULL, SERIAL_BASE::RxIrq); + SERIAL_BASE::attach(NULL, SERIAL_BASE::TxIrq); + + return; +} + +int BufferedSerial::readable(void) +{ + return _rxbuf.available(); // note: look if things are in the buffer +} + +int BufferedSerial::writeable(void) +{ + return 1; // buffer allows overwriting by design, always true +} + +int BufferedSerial::getc(void) +{ + return _rxbuf; +} + +int BufferedSerial::putc(int c) +{ + _txbuf = (char)c; + BufferedSerial::prime(); + + return c; +} + +int BufferedSerial::puts(const char *s) +{ + if (s != NULL) { + const char* ptr = s; + + while(*(ptr) != 0) { + _txbuf = *(ptr++); + } + _txbuf = '\n'; // done per puts definition + BufferedSerial::prime(); + + return (ptr - s) + 1; + } + return 0; +} + +int BufferedSerial::printf(const char* format, ...) +{ + char buffer[this->_buf_size]; + memset(buffer,0,this->_buf_size); + int r = 0; + + va_list arg; + va_start(arg, format); + r = vsprintf(buffer, format, arg); + // this may not hit the heap but should alert the user anyways + if(r > this->_buf_size) { + error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r); + va_end(arg); + return 0; + } + va_end(arg); + r = BufferedSerial::write(buffer, r); + + return r; +} + +ssize_t BufferedSerial::write(const void *s, size_t length) +{ + if (s != NULL && length > 0) { + const char* ptr = (const char*)s; + const char* end = ptr + length; + + while (ptr != end) { + _txbuf = *(ptr++); + } + BufferedSerial::prime(); + + return ptr - (const char*)s; + } + return 0; +} + + +void BufferedSerial::rxIrq(void) +{ + // read from the peripheral and make sure something is available + if(serial_readable(&_serial)) { + _rxbuf = serial_getc(&_serial); // if so load them into a buffer + } + + return; +} + +void BufferedSerial::txIrq(void) +{ + // see if there is room in the hardware fifo and if something is in the software fifo + while(serial_writable(&_serial) && !_cts) { + if(_txbuf.available()) { + serial_putc(&_serial, (int)_txbuf.get()); + } else { + // disable the TX interrupt when there is nothing left to send + SERIAL_BASE::attach(NULL, SERIAL_BASE::TxIrq); + break; + } + } + + return; +} + +void BufferedSerial::prime(void) +{ + // if already busy then the irq will pick this up + if(serial_writable(&_serial) && !_cts) { + SERIAL_BASE::attach(NULL, SERIAL_BASE::TxIrq); // make sure not to cause contention in the irq + BufferedSerial::txIrq(); // only write to hardware in one place + SERIAL_BASE::attach(this, &BufferedSerial::txIrq, SERIAL_BASE::TxIrq); + } + + return; +} + +void BufferedSerial::ctsInterrupt(void) +{ + BufferedSerial::prime(); + return; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial/BufferedSerial.h Fri Jun 12 04:00:23 2015 +0000 @@ -0,0 +1,147 @@ + +/** + * @file BufferedSerial.h + * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUFFEREDSERIAL_H +#define BUFFEREDSERIAL_H + +#include "mbed.h" +#include "Buffer.h" + +// Base Class +#define SERIAL_BASE RawSerial + +/** A serial port (UART) for communication with other serial devices + * + * Can be used for Full Duplex communication, or Simplex by specifying + * one pin as NC (Not Connected) + * + * Example: + * @code + * #include "mbed.h" + * #include "BufferedSerial.h" + * + * BufferedSerial pc(USBTX, USBRX); + * + * int main() + * { + * while(1) + * { + * Timer s; + * + * s.start(); + * pc.printf("Hello World - buffered\n"); + * int buffered_time = s.read_us(); + * wait(0.1f); // give time for the buffer to empty + * + * s.reset(); + * printf("Hello World - blocking\n"); + * int polled_time = s.read_us(); + * s.stop(); + * wait(0.1f); // give time for the buffer to empty + * + * pc.printf("printf buffered took %d us\n", buffered_time); + * pc.printf("printf blocking took %d us\n", polled_time); + * wait(0.5f); + * } + * } + * @endcode + */ + +/** + * @class BufferedSerial + * @brief Software buffers and interrupt driven tx and rx for Serial + */ +class BufferedSerial : public SERIAL_BASE +{ +private: + InterruptIn _cts; + Buffer <char> _rxbuf; + Buffer <char> _txbuf; + uint32_t _buf_size; + uint32_t _tx_multiple; + + void rxIrq(void); + void txIrq(void); + void prime(void); + + void ctsInterrupt(void); + +public: + /** Create a BufferedSerial port, connected to the specified transmit and receive pins + * @param tx Transmit pin + * @param rx Receive pin + * @param cts CTS pin + * @param buf_size printf() buffer size + * @param tx_multiple amount of max printf() present in the internal ring buffer at one time + * @param name optional name + * @note Either tx or rx may be specified as NC if unused + */ + BufferedSerial(PinName tx, PinName rx, PinName cts, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL); + + /** Destroy a BufferedSerial port + */ + virtual ~BufferedSerial(void); + + /** Check on how many bytes are in the rx buffer + * @return 1 if something exists, 0 otherwise + */ + virtual int readable(void); + + /** Check to see if the tx buffer has room + * @return 1 always has room and can overwrite previous content if too small / slow + */ + virtual int writeable(void); + + /** Get a single byte from the BufferedSerial Port. + * Should check readable() before calling this. + * @return A byte that came in on the Serial Port + */ + virtual int getc(void); + + /** Write a single byte to the BufferedSerial Port. + * @param c The byte to write to the Serial Port + * @return The byte that was written to the Serial Port Buffer + */ + virtual int putc(int c); + + /** Write a string to the BufferedSerial Port. Must be NULL terminated + * @param s The string to write to the Serial Port + * @return The number of bytes written to the Serial Port Buffer + */ + virtual int puts(const char *s); + + /** Write a formatted string to the BufferedSerial Port. + * @param format The string + format specifiers to write to the Serial Port + * @return The number of bytes written to the Serial Port Buffer + */ + virtual int printf(const char* format, ...); + + /** Write data to the Buffered Serial Port + * @param s A pointer to data to send + * @param length The amount of data being pointed to + * @return The number of bytes written to the Serial Port Buffer + */ + virtual ssize_t write(const void *s, std::size_t length); +}; + +#endif
--- a/Log/Log.cpp Thu Jun 11 17:40:39 2015 +0000 +++ b/Log/Log.cpp Fri Jun 12 04:00:23 2015 +0000 @@ -1,9 +1,8 @@ #include "Log.h" -Log::Log(PinName tx, PinName rx, PinName cts, PinName mosi, PinName miso, PinName sck, PinName cs) : - _sd(mosi, miso, sck, cs, "sd"), _device(tx, rx), ctsPin(cts){ - buf_send.initialize_buffer(); - //_device.attach(this, &Log::int_serial_tx, Serial::TxIrq); +Log::Log(PinName mosi, PinName miso, PinName sck, PinName cs, PinName tx, PinName rx, PinName cts) : + _sd(mosi, miso, sck, cs, "sd"), _device(tx, rx, cts){ + } int Log::initialize_sdlog(const char* str){ @@ -16,10 +15,8 @@ sprintf(filename, "/sd/log%03d.csv", n+1); fp = fopen(filename, "w"); + fprintf(fp, str); _device.printf(str); - fprintf(fp, str); - fflush(fp); - return 1; } @@ -36,7 +33,7 @@ struct dirent *dirst; dp = opendir("/sd/"); if (!dp){ - printf("Could not open directry\n"); + error("Could not open directry.\n"); return -1; } while((dirst = readdir(dp)) != NULL) { @@ -48,87 +45,7 @@ return n; } -void Log::puts(const char* str){ - fputs(str, fp); - fflush(fp); - //while(!_device.writeable()); - for(int i=0; str[i] != '\0'; i++) { - while(ctsPin); - _device.putc(str[i]); - } - /*int16_t len=strlen(str); - int16_t capa=buf_send.buffer_capacity(); - bool empty=buf_send.is_buffer_empty(); - char ch; - if(len>capa){ - len=capa; - } - buf_send.write_buffer((const uint8_t*)str, 0, len); - if((_device.writeable()) && (empty)){ - ch=buf_send.read_buffer_byte(); - _device.putc(ch); - fputc(ch, fp); - fflush(fp); - }*/ -} - -void Log::putc(char ch){ - - int16_t capa=buf_send.buffer_capacity(); - if(capa==0) return; - buf_send.write_buffer_byte(ch); - -} - -void Log::write_data(uint8_t* buf, int16_t size){ - int capa=buf_send.buffer_capacity(); - if(size>capa){ - size=capa; - } - buf_send.write_buffer(buf, 0, size); -} - -bool Log::is_empty(){ - return buf_send.is_buffer_empty(); -} - -int16_t Log::recieve_buffer_size(){ - return buf_recieve.buffer_size(); -} - -int16_t Log::getc(){ - if(buf_recieve.is_buffer_empty()){ - return -1; - } - return buf_recieve.read_buffer_byte(); -} - -int16_t Log::read_data(uint8_t* buf, int16_t size){ - int len=buf_recieve.buffer_size(); - if(size>len){ - size=len; - } - buf_recieve.read_buffer(buf, 0, size); - return size; -} - -char Log::int_tx(){ - return buf_send.read_buffer_byte(); -} - -void Log::int_serial_tx(){ - /*char ch; - while((_device.writeable()) && (buf_send.is_buffer_empty()==false)){ - ch=buf_send.read_buffer_byte(); - _device.putc(ch); - fputc(ch, fp); - }*/ - - uint8_t buf[RING_BUFFER_SIZE] = {}; - int data_num = buf_send.read_buffer_all(buf); - if(data_num != 0) { - _device.printf((const char*)buf); - fputs((const char*)buf, fp); - fflush(fp); - } +void Log::write(const char* str){ + fprintf(fp, str); + _device.printf(str); } \ No newline at end of file
--- a/Log/Log.h Thu Jun 11 17:40:39 2015 +0000 +++ b/Log/Log.h Fri Jun 12 04:00:23 2015 +0000 @@ -8,31 +8,20 @@ #include "mbed.h" #include "SDFileSystem.h" -#include "RingBuffer.h" +#include "BufferedSerial.h" class Log{ public: - Log(PinName tx, PinName rx, PinName cts, PinName mosi, PinName miso, PinName sck, PinName cs); + Log(PinName mosi, PinName miso, PinName sck, PinName cs, PinName tx, PinName rx, PinName cts); int initialize_sdlog(const char* str); void close(); int find_last(); - void puts(const char *str); - void putc(char ch); - void write_data(uint8_t* buf, int16_t size); - bool is_empty(); - int16_t recieve_buffer_size(); - int16_t getc(); - int16_t read_data(uint8_t* buf, int16_t size); - char int_tx(); - void int_serial_tx(); + void write(const char* str); protected: SDFileSystem _sd; + BufferedSerial _device; FILE *fp; - Serial _device; - DigitalIn ctsPin; - RingBuffer buf_send; - RingBuffer buf_recieve; }; #endif /* LOG_H_ */ \ No newline at end of file
--- a/main.cpp Thu Jun 11 17:40:39 2015 +0000 +++ b/main.cpp Fri Jun 12 04:00:23 2015 +0000 @@ -27,7 +27,7 @@ Serial pc(SERIAL_TX, SERIAL_RX); // PC通信用シリアルポート GMS6_CR6 gms(&gps, &pc); // GPS Ticker INT_timer; // 割り込みタイマー -Log logger(PA_9, PA_10, PC_1, PB_5, PB_4, PB_3, PB_10); // ロガー(microSD、XBee) +Log logger(PB_5, PB_4, PB_3, PB_10, PA_9, PA_10, PC_1); // ロガー(microSD、XBee) PwmOut servoL(PC_7), servoR(PB_6); AnalogIn rf(PC_0); AnalogIn servoVcc(PA_0); @@ -65,7 +65,7 @@ Timer timer; -char data[1024] = {}; +char data[512] = {}; /********** private functions **********/ void KalmanInit(); // カルマンフィルタ初期化 @@ -84,7 +84,7 @@ if(!hmc.init()) AbortWithMsg("hmc5883l Initialize Error !!"); // hmc5883l初期化 char* title = "log data\r\n"; // ログのタイトル行 - if(!logger.initialize_sdlog(title)) return 0; // ログファイル初期設定 + logger.initialize_sdlog(title); // ログファイル初期設定 KalmanInit(); @@ -115,7 +115,7 @@ geomag.GetComp(1), geomag.GetComp(2), geomag.GetComp(3), press, gms.longitude, gms.latitude, sv, lv, gms.Ns); - logger.puts(data); + logger.write(data); INT_flag = TRUE; // 割り込み許可