From 039b202e5c68834801d23e22eecc7cae2879ea83 Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 28 Mar 2017 11:21:15 +0200 Subject: [PATCH] ARDUINO as Master --- src/Makefile.am | 2 +- src/main.cpp | 10 +- src/owARDUINOInterface.cpp | 489 +++++++++++++++++++++++++++++++++++++ src/owARDUINOInterface.h | 77 ++++++ src/owDeviceConfig.cpp | 1 + src/owInterface.h | 4 +- src/owTools.h | 2 +- 7 files changed, 580 insertions(+), 5 deletions(-) create mode 100644 src/owARDUINOInterface.cpp create mode 100644 src/owARDUINOInterface.h diff --git a/src/Makefile.am b/src/Makefile.am index 3f69e36..2dc8b37 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -Wall -std=c++11 -I/usr/include/mysql owToolsprgdir=../ owToolsprg_PROGRAMS=owTools -owTools_SOURCES=main.cpp mySensorDB.cpp owInterface.cpp owPiGPioInterface.cpp libusbds2490.c owUSBInterface.cpp hexfile.cpp owCOMInterface.cpp owDevice.cpp owDeviceConfig.cpp +owTools_SOURCES=main.cpp mySensorDB.cpp owInterface.cpp owPiGPioInterface.cpp libusbds2490.c owUSBInterface.cpp hexfile.cpp owCOMInterface.cpp owDevice.cpp owDeviceConfig.cpp owARDUINOInterface.cpp owTools_LDADD = -lpthread -lrt -lusb -lmysqlclient diff --git a/src/main.cpp b/src/main.cpp index b629617..c36dd88 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -412,6 +412,12 @@ int main(int argc, char *argv[]) { printf("Open /dev/ttyS%i\n",port); owi->InitAdapter(port); } else + if(adapter.find("ARDUINO")!=std::string::npos) { + owi=new owARDUINOInterface(); + int port=atoi(adapter.substr(adapter.find("ARDUINO")+7).c_str()); + printf("Open /dev/ttyS%i\n",port); + owi->InitAdapter(port); + } else if(adapter.find("USB")!=std::string::npos) { owi=new owUSBInterface(); int port=atoi(adapter.substr(adapter.find("USB")+3).c_str()); @@ -439,11 +445,13 @@ int main(int argc, char *argv[]) { } } if (owi==NULL) { + printf("No 1-Wiremaster found\n"); return 0; } setLogMode(); - + + if (getArg("i")=="1") { interactive(owi); diff --git a/src/owARDUINOInterface.cpp b/src/owARDUINOInterface.cpp new file mode 100644 index 0000000..33d2814 --- /dev/null +++ b/src/owARDUINOInterface.cpp @@ -0,0 +1,489 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// 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. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de 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. + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "owARDUINOInterface.h" + +#define MODE_DATA 0xE1 +#define MODE_COMMAND 0xE3 + +// Baud rate bits +#define PARMSET_9600 0x00 +#define PARMSET_19200 0x02 +#define PARMSET_57600 0x04 +#define PARMSET_115200 0x06 + + + +#define COM_IDENTIFER 1 +#define COM_RESET 2 +#define COM_SEARCH_INIT 3 +#define COM_SEARCH_NEXT 4 +#define COM_BLOCK 5 +#define COM_SBYTE 6 +#define COM_RBYTE 7 +#define COM_SBIT 8 +#define COM_RBIT 9 + +//--------------------------------------------------------------------------- +// Description: +// flush the rx and tx buffers +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owARDUINOInterface::FlushCOM() { + tcflush(fd, TCIOFLUSH); +} + + +int owARDUINOInterface::OpenCOM(uint8_t comnr) { + struct termios t; // see man termios - declared as above + int rc; + //int fd; + char port_zstr[100]; + if (com_init) return fd; + + sprintf(port_zstr,"/dev/ttyUSB%i",comnr); + + fd = open(port_zstr, O_RDWR|O_NONBLOCK| O_NOCTTY ); + if (fd<0) + { + log->set(OWLOG_ERROR,"ERROR open Com %s return %i",port_zstr,fd); + return fd; + } + rc = tcgetattr (fd, &t); + if (rc < 0) + { + int tmp; + tmp = errno; + close(fd); + errno = tmp; + log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr); + return rc; // changed (2.00), used to return rc; + } + + cfsetospeed(&t, B9600); + cfsetispeed (&t, B9600); + + // Get terminal parameters. (2.00) removed raw + tcgetattr(fd,&t); + // Save original settings. + origterm = t; + + t.c_cflag &= ~PARENB; // Make 8n1 + t.c_cflag &= ~CSTOPB; + t.c_cflag &= ~CSIZE; + t.c_cflag |= CS8; + + t.c_cflag &= ~CRTSCTS; // no flow control + t.c_cc[VMIN] = 1; // read doesn't block + t.c_cc[VTIME] = 5; // 0.5 seconds read timeout + t.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines + t.c_cflag &= ~CRTSCTS; // no flow control + t.c_iflag &= ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl +/* Make raw */ + cfmakeraw(&t); + tcflush(fd,TCIOFLUSH); + + rc = tcsetattr(fd, TCSAFLUSH, &t); + + if (rc < 0) + { + int tmp; + tmp = errno; + close(fd); + errno = tmp; + log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr); + return rc; // changed (2.00), used to return rc; + } + com_init=1; + return fd; // changed (2.00), used to return fd; +} + + +//--------------------------------------------------------------------------- +// Closes the connection to the port. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owARDUINOInterface::CloseCOM() +{ + // restore tty settings + tcsetattr(fd, TCSAFLUSH, &origterm); + FlushCOM(); + close(fd); + com_init=0; + +} + + +//-------------------------------------------------------------------------- +// Write an array of bytes to the COM port, verify that it was +// sent out. Assume that baud rate has been set. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will +// be used to indicate the port number desired when calling +// all other functions in this library. +// Returns 1 for success and 0 for failure +// +int owARDUINOInterface::WriteCOM( int outlen, uint8_t *outbuf) +{ + long count = outlen; + int i=0; + for (int k=0;kset(OWLOG_ERROR,"Read Error on Serial"); + + return cnt; + } + } + else { + log->set(OWLOG_ERROR,"Read Error on Serial (select)"); + return cnt; + } + } + + + // success, so return desired length + return inlen; +} + + + + +//-------------------------------------------------------------------------- +// Description: +// Send a break on the com port for at least 2 ms +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +void owARDUINOInterface::BreakCOM() +{ + int duration = 0; // see man termios break may be + tcsendbreak(fd, duration); // too long +} + + +//-------------------------------------------------------------------------- +// Set the baud rate on the com port. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'new_baud' - new baud rate defined as +// PARMSET_9600 0x00 +// PARMSET_19200 0x02 +// PARMSET_57600 0x04 +// PARMSET_115200 0x06 +// +void owARDUINOInterface::SetBaudCOM( uint8_t new_baud) +{ + struct termios t; + int rc; + speed_t baud; + + // read the attribute structure + rc = tcgetattr(fd, &t); + if (rc < 0) + { + close(fd); + log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)"); + + return; + } + + // convert parameter to linux baud rate + switch(new_baud) + { + case PARMSET_9600: + baud = B9600; + break; + case PARMSET_19200: + baud = B19200; + break; + case PARMSET_57600: + baud = B57600; + break; + case PARMSET_115200: + baud = B115200; + break; + default: + baud = B9600; + break; + } + + // set baud in structure + cfsetospeed(&t, baud); + cfsetispeed(&t, baud); + + // change baud on port + rc = tcsetattr(fd, TCSAFLUSH, &t); + if (rc < 0) { + log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)"); + + close(fd); + } +} + + + + + + + + + + + + + + + + + +int owARDUINOInterface::InitAdapter(uint8_t nr) { + // attempt to open the communications port + if ((fd = OpenCOM(nr)) < 0) + { + log->set(OWLOG_ERROR,"OWERROR_OPENCOM_FAILED"); + return -1; + } + sleep(2); + uint8_t readbuffer[20],sendpacket[20]; + uint8_t sendlen=0; + sendpacket[sendlen++]=0x01; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x03; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(3,readbuffer)) == 3) { + + // printf("%02X %02X %02X\n",readbuffer[0],readbuffer[1],readbuffer[2] ); + + + + } else { + //printf("%i\n",sendlen); + log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED"); + } + } else log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); + + com_init=1; + + + return 1; +} + + +int owARDUINOInterface::owFirst() { + uint8_t readbuffer[20],sendpacket[20]; + uint8_t sendlen=0; + sendpacket[sendlen++]=0x03; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x08; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(8,readbuffer)) == 8) { + if (readbuffer[0]!=0) { + for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i]; + return 1; + } + } + } + return 0; + +} +int owARDUINOInterface::owNext() { + uint8_t readbuffer[20],sendpacket[20]; + uint8_t sendlen=0; + sendpacket[sendlen++]=0x04; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x08; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(8,readbuffer)) == 8) { + if (readbuffer[0]!=0) { + for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i]; + return 1; + } + } + } + return 0; + +} + + +void owARDUINOInterface::ReleaseAdapter() { + CloseCOM(); +} + + +int owARDUINOInterface::Reset() { + uint8_t readbuffer[5],sendpacket[5]; + uint8_t sendlen=0; + /* size_t l; + + if ((l=read(fd,readbuffer,5))>0) { + printf("in buf %i bytes %02X %02X %02X %02X %02X\n",l,readbuffer[0],readbuffer[1],readbuffer[2],readbuffer[3],readbuffer[4]); + }*/ + sendlen=0; + sendpacket[sendlen++]=0x02; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x01; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(1,readbuffer)) == 1) { + // printf("Reset %i\n",readbuffer[0]); + if (readbuffer[0]) return 1; + + } + } + + return 0; +} + + +uint8_t owARDUINOInterface::sendrecivByte(uint8_t byte) { + + uint8_t readbuffer[5],sendpacket[5]; + uint8_t sendlen=0; +/* size_t l; + if ((l=read(fd,readbuffer,5))>0) { + printf("in buf %i bytes %02X %02X %02X %02X %02X\n",l,readbuffer[0],readbuffer[1],readbuffer[2],readbuffer[3],readbuffer[4]); + }*/ + if (byte!=0xFF) { + sendlen=0; + sendpacket[sendlen++]=COM_SBYTE; + sendpacket[sendlen++]=0x01; + sendpacket[sendlen++]=0x01; + sendpacket[sendlen++]=byte; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(1,readbuffer)) == 1) { + // printf("Send %02X %02X \n",byte,readbuffer[0]); + + return byte; + } + } + } else { + sendlen=0; + sendpacket[sendlen++]=COM_RBYTE; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x01; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(1,readbuffer)) == 1) { + // printf("Recive %02X\n",readbuffer[0]); + return readbuffer[0]; + } + } + + } + + return 0; +} +uint8_t owARDUINOInterface::sendrecivBit(uint8_t bit) { + return 0; +} + +int owARDUINOInterface::Communicate(std::vector *data, int scount, int rcount) { + int i=0; + data->resize(scount); + uint8_t readbuffer[128],sendpacket[128+3]; + uint8_t sendlen=0; + sendpacket[sendlen++]=COM_BLOCK; + sendpacket[sendlen++]=scount; + sendpacket[sendlen++]=rcount; + for(uint8_t v:*data) { + sendpacket[sendlen++]=v; + (*data)[i]=v;i++; + } + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(rcount,readbuffer)) == rcount) { + for(i=0;ipush_back(readbuffer[i]); + } + //printf("\n"); + } + } + + + return 0; +} + diff --git a/src/owARDUINOInterface.h b/src/owARDUINOInterface.h new file mode 100644 index 0000000..9dc72cb --- /dev/null +++ b/src/owARDUINOInterface.h @@ -0,0 +1,77 @@ +// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +// All rights reserved. +// +// 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. +// * All advertising materials mentioning features or use of this +// software must display the following acknowledgement: This product +// includes software developed by tm3d.de and its contributors. +// * Neither the name of tm3d.de 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 __OWARDUINOINTERFACES_H_ +#define __OWARDUINOINTERFACES_H_ + +#include "owInterface.h" + +class owARDUINOInterface:public owInterface{ +protected: + int fd; + int com_init; +public: + owARDUINOInterface():owInterface() { + fd=0; + com_init=0; + } + virtual int InitAdapter(uint8_t); + virtual int Reset(); + virtual uint8_t sendrecivBit(uint8_t bit); + virtual uint8_t sendrecivByte(uint8_t byte); + virtual void ReleaseAdapter(); + virtual int owFirst(); + virtual int owNext(); + virtual int Communicate(std::vector *data, int scount, int rcount); + + +protected: + uint8_t ULevel; // current DS2480B 1-Wire Net level + uint8_t UBaud; // current DS2480B baud rate + uint8_t UMode; // current DS2480B command or data mode state + uint8_t USpeed; // current DS2480B 1-Wire Net communication speed + uint8_t UVersion; // current DS2480B version + struct termios origterm; + + + int OpenCOM(uint8_t comnr); + void CloseCOM(); + void FlushCOM(); + int WriteCOM(int outlen, uint8_t *outbuf); + int ReadCOM(int inlen, uint8_t *inbuf); + void BreakCOM(); + void SetBaudCOM(uint8_t new_baud); + +}; + +#endif diff --git a/src/owDeviceConfig.cpp b/src/owDeviceConfig.cpp index 9262567..963b3a0 100644 --- a/src/owDeviceConfig.cpp +++ b/src/owDeviceConfig.cpp @@ -244,6 +244,7 @@ double owDeviceConfig::calculateValueFromNumber(int code, int vn, std::vector