First Publish
Dependencies: BridgeDriver2 FrontPanelButtons MAX31855 MCP23017 SDFileSystem TextLCD mbed
Revision 0:20e78c9d2ea9, committed 2014-11-10
- Comitter:
- mehatfie
- Date:
- Mon Nov 10 22:56:20 2014 +0000
- Child:
- 1:9954bf6d7d25
- Commit message:
- First Commit of Falcon Wing
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BridgeDriver.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/BridgeDriver/#6561ddb98d6e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18B20.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,103 @@
+/*
+* DS18B20. Maxim DS18B20 One-Wire Thermometer.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DS18B20.h"
+#include "DebugTrace.h"
+
+DebugTrace pc_ds18B20(ON, TO_SERIAL);
+
+DS18B20::DS18B20(bool crcOn, bool useAddr, bool parasitic, PinName pin) :
+ OneWireThermometer(crcOn, useAddr, parasitic, pin, DS18B20_ID)
+{
+}
+
+void DS18B20::setResolution(eResolution resln)
+{
+ // as the write to the configuration register involves a write to the
+ // high and low alarm bytes, need to read these registers first
+ // and copy them back on the write
+
+ BYTE read_data[THERMOM_SCRATCHPAD_SIZE];
+ BYTE write_data[ALARM_CONFIG_SIZE];
+
+ if (readAndValidateData(read_data))
+ {
+ // copy alarm and config data to write data
+ for (int k = 2; k < 5; k++)
+ {
+ write_data[k - 2] = read_data[k];
+ }
+ int config = write_data[2];
+ config &= 0x9F;
+ config ^= (resln << 5);
+ write_data[2] = config;
+
+ resetAndAddress();
+ oneWire.writeByte(WRITESCRATCH);
+ for (int k = 0; k < 3; k++)
+ {
+ oneWire.writeByte(write_data[k]);
+ }
+
+ // remember it so we can use the correct delay in reading the temperature
+ // for parasitic power
+ resolution = resln;
+ }
+}
+
+float DS18B20::calculateTemperature(BYTE* data)
+{
+ bool signBit = false;
+ if (data[TEMPERATURE_MSB] & 0x80) signBit = true;
+
+ int read_temp = (data[TEMPERATURE_MSB] << 8) + data[TEMPERATURE_LSB];
+ if (signBit)
+ {
+ read_temp = (read_temp ^ 0xFFFF) + 1; // two's complement
+ read_temp *= -1;
+ }
+
+ int resolution = (data[CONFIG_REG_BYTE] & 0x60) >> 5; // mask off bits 6,5 and move to 1,0
+ switch (resolution)
+ {
+ case nineBit: // 0.5 deg C increments
+ read_temp &= 0xFFF8; // bits 2,1,0 are undefined
+ //pc_ds18B20.traceOut("9 bit resolution ...\r\n");
+ break;
+ case tenBit: // 0.25 deg C increments
+ read_temp &= 0xFFFC; // bits 1,0 are undefined
+ //pc_ds18B20.traceOut("10 bit resolution ...\r\n");
+ break;
+ case elevenBit: // 0.125 deg C increments
+ read_temp &= 0xFFFE; // bit 0 is undefined
+ //pc_ds18B20.traceOut("11 bit resolution ...\r\n");
+ break;
+ case twelveBit: // 0.0625 deg C increments
+ //pc_ds18B20.traceOut("12 bit resolution ...\r\n");
+ break;
+ }
+ float realTemp = (float)read_temp/16 ;
+
+ //pc_ds18B20.traceOut("TEMP_READ/REAL TEMP: %f \r\n", realTemp);
+
+ return realTemp;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18B20.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,41 @@
+/*
+* DS18B20. Maxim DS18B20 One-Wire Thermometer.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SNATCH59_DS18B20_H
+#define SNATCH59_DS18B20_H
+
+#include "OneWireThermometer.h"
+#include "OneWireDefs.h"
+
+class DS18B20 : public OneWireThermometer
+{
+public:
+ DS18B20(bool crcOn, bool useAddr, bool parasitic, PinName pin);
+
+ virtual void setResolution(eResolution resln);
+
+protected:
+ virtual float calculateTemperature(BYTE* data);
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18S20.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,55 @@
+/*
+* DS18S20. Maxim DS18S20 One-Wire Thermometer.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DS18S20.h"
+#include "DebugTrace.h"
+
+DebugTrace pc_ds18S20(ON, TO_SERIAL);
+
+DS18S20::DS18S20(bool crcOn, bool useAddr, bool parasitic, PinName pin) :
+ OneWireThermometer(crcOn, useAddr, parasitic, pin, DS18S20_ID)
+{
+}
+
+float DS18S20::calculateTemperature(BYTE* data)
+{
+ // DS18S20 basic resolution is always 9 bits, which can be enhanced as follows
+ bool signBit = false;
+ if (data[TEMPERATURE_MSB] & 0x80) signBit = true;
+
+ int read_temp = (data[TEMPERATURE_MSB] << 8) + data[TEMPERATURE_LSB];
+ if (signBit)
+ {
+ read_temp = (read_temp ^ 0xFFFF) + 1; // two's complement
+ read_temp *= -1;
+ }
+
+ float readTemp = (float)read_temp/2 ; // divide by 2
+ pc_ds18S20.traceOut("TEMP_READ: %f \r\n", readTemp); // 9 bit resolution value
+
+ // convert to real temperature
+ float tempCount = float(data[COUNT_PER_DEG_BYTE] - data[COUNT_REMAIN_BYTE])/(float)data[COUNT_PER_DEG_BYTE];
+ float realTemp = (readTemp - 0.25) + tempCount;
+ pc_ds18S20.traceOut("Temperature: %f \r\n", realTemp); // enhanced resolution value
+
+ return realTemp;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18S20.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,39 @@
+/*
+* DS18S20. Maxim DS18S20 One-Wire Thermometer.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SNATCH59_DS18S20_H
+#define SNATCH59_DS18S20_H
+
+#include "OneWireThermometer.h"
+
+class DS18S20 : public OneWireThermometer
+{
+public:
+ DS18S20(bool crcOn, bool useAddr, bool parasitic, PinName pin);
+
+ virtual void setResolution(eResolution resln) { }; // do nothing
+
+protected:
+ virtual float calculateTemperature(BYTE* data);
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DebugTrace.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,143 @@
+/*
+* DebugTrace. Allows dumping debug messages/values to serial or
+* to file.
+*
+* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of DebugTrace.
+*
+* DebugTrace is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DebugTrace is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DebugTrace.h"
+#include <mbed.h>
+#include <stdarg.h>
+#include <string.h>
+
+Serial logSerial(USBTX, USBRX);
+LocalFileSystem local("local");
+
+const char* FILE_PATH = "/local/";
+const char* EXTN = ".bak";
+
+DebugTrace::DebugTrace(eLog on, eLogTarget mode, const char* fileName, int maxSize) :
+ enabled(on), logMode(mode), maxFileSize(maxSize), currentFileSize(0),
+ logFileStatus(0)
+{
+ // allocate memory for file name strings
+ int str_size = (strlen(fileName) + strlen(FILE_PATH) + strlen(EXTN) + 1) * sizeof(char);
+ logFile = (char*)malloc(str_size);
+ logFileBackup = (char*)malloc(str_size);
+
+ // add path to log file name
+ strcpy(logFile, FILE_PATH);
+ strcat(logFile, fileName);
+
+ // create backup file name
+ strcpy(logFileBackup, logFile);
+ strcpy(logFileBackup, strtok(logFileBackup, "."));
+ strcat(logFileBackup, EXTN);
+}
+
+DebugTrace::~DebugTrace()
+{
+ // dust to dust, ashes to ashes
+ if (logFile != NULL) free(logFile);
+ if (logFileBackup != NULL) free(logFileBackup);
+}
+
+void DebugTrace::clear()
+{
+ // don't care about whether these fail
+ remove(logFile);
+ remove(logFileBackup);
+}
+
+void DebugTrace::backupLog()
+{
+ // delete previous backup file
+ if (remove(logFileBackup))
+ {
+ // standard copy stuff
+ char ch;
+ FILE* to = fopen(logFileBackup, "wb");
+ if (NULL != to)
+ {
+ FILE* from = fopen(logFile, "rb");
+ if (NULL != from)
+ {
+ while(!feof(from))
+ {
+ ch = fgetc(from);
+ if (ferror(from)) break;
+
+ if(!feof(from)) fputc(ch, to);
+ if (ferror(to)) break;
+ }
+ }
+
+ if (NULL != from) fclose(from);
+ if (NULL != to) fclose(to);
+ }
+ }
+
+ // now delete the log file, so we are ready to start again
+ // even if backup creation failed - the show must go on!
+ logFileStatus = remove(logFile);
+}
+
+void DebugTrace::traceOut(const char* fmt, ...)
+{
+ if (enabled)
+ {
+ va_list ap; // argument list pointer
+ va_start(ap, fmt);
+
+ if (TO_SERIAL == logMode)
+ {
+ vfprintf(logSerial, fmt, ap);
+ }
+ else // TO_FILE
+ {
+ if (0 == logFileStatus) // otherwise we failed to remove a full log file
+ {
+ // Write data to file. Note the file size may go over limit
+ // as we check total size afterwards, using the size written to file.
+ // This is not a big issue, as this mechanism is only here
+ // to stop the file growing unchecked. Just remember log file sizes may
+ // be some what over (as apposed to some what under), so don't push it
+ // with the max file size.
+ FILE* fp = fopen(logFile, "a");
+ if (NULL == fp)
+ {
+ va_end(ap);
+ return;
+ }
+ int size_written = vfprintf(fp, fmt, ap);
+ fclose(fp);
+
+ // check if we are over the max file size
+ // if so backup file and start again
+ currentFileSize += size_written;
+ if (currentFileSize >= maxFileSize)
+ {
+ backupLog();
+ currentFileSize = 0;
+ }
+ }
+ }
+
+ va_end(ap);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DebugTrace.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,50 @@
+/*
+* DebugTrace. Allows dumping debug messages/values to serial or
+* to file.
+*
+* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of DebugTrace.
+*
+* DebugTrace is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DebugTrace is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SNATCH59_DEBUGTRACE_H
+#define SNATCH59_DEBUGTRACE_H
+
+enum eLog {OFF, ON};
+enum eLogTarget {TO_SERIAL, TO_FILE};
+
+class DebugTrace
+{
+public:
+ DebugTrace(eLog on, eLogTarget mode, const char* fileName = "log.txt", const int maxSize = 1024);
+ ~DebugTrace();
+
+ void clear();
+ void traceOut(const char* fmt, ...);
+
+private:
+ eLog enabled;
+ eLogTarget logMode;
+ int maxFileSize;
+ int currentFileSize;
+ char* logFile;
+ char* logFileBackup;
+ int logFileStatus; // if things go wrong, don't write any more data to file
+
+ void backupLog();
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FrontPanelButtons.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/FrontPanelButtons/#b2844843297f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LocalPinNames.h Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,36 @@ +#ifndef LOCALPINNAMES_H + +#define LOCALPINNAMES_H + + /* local name, resouce name */ +#define DIO0 P2_2 +#define DIO1 P2_3 +#define DIO2 P2_4 +#define DIO3 P2_5 +#define DIO4 P2_6 +#define DIO5 P2_7 +#define DIO6 P2_8 +#define DIO7 P2_9 +#define DIO8 P1_1 +#define DIO9 P1_4 +#define DIO10 P1_8 +#define DIO11 P1_9 +#define SS1 P0_19 +#define SS2 P0_20 +#define SS3 P0_21 +#define SS4 P0_22 +#define SS_ADC P1_0 +#define AI0 P0_23 +#define AI1 P0_24 +#define AI2 P0_25 +#define AI3 P0_26 +#define AI4 P1_30 +#define AI5 P1_31 +#define KILL P2_11 +#define CAN1_RX P0_0 +#define CAN1_TX P0_1 +#define CAN2_RX P0_4 +#define CAN2_TX P0_5 + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX31855.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/Stavlin/code/MAX31855/#b0c2b7f72cb9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP23017.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/wim/code/MCP23017/#5696b886a895
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWireCRC.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,459 @@
+/*
+* OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire
+* library. Please see additional copyrights below this one, including
+* references to other copyrights.
+*
+* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireCRC.
+*
+* OneWireCRC is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireCRC is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+Copyright (c) 2007, Jim Studt
+
+Updated to work with arduino-0008 and to include skip() as of
+2007/07/06. --RJL20
+
+Modified to calculate the 8-bit CRC directly, avoiding the need for
+the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
+-- Tom Pollard, Jan 23, 2008
+
+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.
+
+Much of the code was inspired by Derek Yerger's code, though I don't
+think much of that remains. In any event that was..
+ (copyleft) 2006 by Derek Yerger - Free to distribute freely.
+
+The CRC code was excerpted and inspired by the Dallas Semiconductor
+sample code bearing this copyright.
+//---------------------------------------------------------------------------
+// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
+//
+// 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 DALLAS SEMICONDUCTOR 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.
+//
+// Except as contained in this notice, the name of Dallas Semiconductor
+// shall not be used except as stated in the Dallas Semiconductor
+// Branding Policy.
+//--------------------------------------------------------------------------
+*/
+
+#include "OneWireCRC.h"
+#include "OneWireDefs.h"
+
+// recommended data sheet timings in micro seconds
+const int standardT[] = {6, 64, 60, 10, 9, 55, 0, 480, 70, 410};
+const int overdriveT[] = {1.5, 7.5, 7.5, 2.5, 0.75, 7, 2.5, 70, 8.5, 40};
+
+OneWireCRC::OneWireCRC(PinName oneWire, eSpeed speed) : oneWirePort(oneWire)
+{
+ if (STANDARD == speed) timing = standardT;
+ else timing = overdriveT; // overdrive
+
+ resetSearch(); // reset address search state
+}
+
+// Generate a 1-wire reset, return 1 if no presence detect was found,
+// return 0 otherwise.
+// (NOTE: does not handle alarm presence from DS2404/DS1994)
+int OneWireCRC::reset()
+{
+
+ BYTE result = 0; // sample presence pulse result
+
+ wait_us(timing[6]);
+ oneWirePort.output();
+ oneWirePort = 0;
+ wait_us(timing[7]);
+ oneWirePort.input();
+ wait_us(timing[8]);
+ result = !(oneWirePort & 0x01);
+ wait_us(timing[9]);
+
+ return result;
+}
+
+//
+// Write a bit. Port and bit is used to cut lookup time and provide
+// more certain timing.
+//
+void OneWireCRC::writeBit(int bit)
+{
+ bit = bit & 0x01;
+
+ if (bit)
+ {
+ // Write '1' bit
+ oneWirePort.output();
+ oneWirePort = 0;
+ wait_us(timing[0]);
+ oneWirePort.input();
+ wait_us(timing[1]);
+ }
+ else
+ {
+ // Write '0' bit
+ oneWirePort.output();
+ oneWirePort = 0;
+ wait_us(timing[2]);
+ oneWirePort.input();
+ wait_us(timing[3]);
+ }
+}
+
+//
+// Read a bit. Port and bit is used to cut lookup time and provide
+// more certain timing.
+//
+int OneWireCRC::readBit()
+{
+ BYTE result;
+
+ oneWirePort.output();
+ oneWirePort = 0;
+ wait_us(timing[0]);
+ oneWirePort.input();
+ wait_us(timing[4]);
+ result = oneWirePort & 0x01;
+ wait_us(timing[5]);
+
+ return result;
+}
+
+//
+// Write a byte. The writing code uses the active drivers to raise the
+// pin high, if you need power after the write (e.g. DS18S20 in
+// parasite power mode) then set 'power' to 1, otherwise the pin will
+// go tri-state at the end of the write to avoid heating in a short or
+// other mishap.
+//
+void OneWireCRC::writeByte(int data)
+{
+ // Loop to write each bit in the byte, LS-bit first
+ for (int loop = 0; loop < 8; loop++)
+ {
+ writeBit(data & 0x01);
+
+ // shift the data byte for the next bit
+ data >>= 1;
+ }
+}
+
+//
+// Read a byte
+//
+int OneWireCRC::readByte()
+{
+ int result = 0;
+
+ for (int loop = 0; loop < 8; loop++)
+ {
+ // shift the result to get it ready for the next bit
+ result >>= 1;
+
+ // if result is one, then set MS bit
+ if (readBit()) result |= 0x80;
+ }
+
+ return result;
+}
+
+int OneWireCRC::touchByte(int data)
+{
+ int result = 0;
+
+ for (int loop = 0; loop < 8; loop++)
+ {
+ // shift the result to get it ready for the next bit
+ result >>= 1;
+
+ // If sending a '1' then read a bit else write a '0'
+ if (data & 0x01)
+ {
+ if (readBit()) result |= 0x80;
+ }
+ else writeBit(0);
+
+ // shift the data byte for the next bit
+ data >>= 1;
+ }
+
+ return result;
+}
+
+void OneWireCRC::block(BYTE* data, int data_len)
+{
+ for (int loop = 0; loop < data_len; loop++)
+ {
+ data[loop] = touchByte(data[loop]);
+ }
+}
+
+int OneWireCRC::overdriveSkip(BYTE* data, int data_len)
+{
+ // set the speed to 'standard'
+ timing = standardT;
+
+ // reset all devices
+ if (reset()) return 0; // if no devices found
+
+ // overdrive skip command
+ writeByte(OVERDRIVE_SKIP);
+
+ // set the speed to 'overdrive'
+ timing = overdriveT;
+
+ // do a 1-Wire reset in 'overdrive' and return presence result
+ return reset();
+}
+
+//
+// Do a ROM select
+//
+void OneWireCRC::matchROM(BYTE rom[8])
+{
+ writeByte(MATCH_ROM); // Choose ROM
+
+ for(int i = 0; i < 8; i++) writeByte(rom[i]);
+}
+
+//
+// Do a ROM skip
+//
+void OneWireCRC::skipROM()
+{
+ writeByte(SKIP_ROM); // Skip ROM
+}
+
+//
+// You need to use this function to start a search again from the beginning.
+// You do not need to do it for the first search, though you could.
+//
+void OneWireCRC::resetSearch()
+{
+ searchJunction = -1;
+ searchExhausted = false;
+ for (int i = 0; i < 8; i++)
+ {
+ address[i] = 0;
+ }
+}
+
+//
+// Perform a search. If this function returns a '1' then it has
+// enumerated the next device and you may retrieve the ROM from the
+// OneWire::address variable. If there are no devices, no further
+// devices, or something horrible happens in the middle of the
+// enumeration then a 0 is returned. If a new device is found then
+// its address is copied to newAddr. Use OneWire::reset_search() to
+// start over.
+//
+BYTE OneWireCRC::search(BYTE* newAddr)
+{
+ BYTE i;
+ int lastJunction = -1;
+ BYTE done = 1;
+
+ if (searchExhausted) return 0;
+
+ if (!reset()) return 0;
+
+ writeByte(SEARCH_ROM);
+
+ for(i = 0; i < 64; i++)
+ {
+ BYTE a = readBit( );
+ BYTE nota = readBit( );
+ BYTE ibyte = i/8;
+ BYTE ibit = 1 << (i & 7);
+
+ // I don't think this should happen, this means nothing responded, but maybe if
+ // something vanishes during the search it will come up.
+ if (a && nota) return 0;
+
+ if (!a && !nota)
+ {
+ if (i == searchJunction)
+ {
+ // this is our time to decide differently, we went zero last time, go one.
+ a = 1;
+ searchJunction = lastJunction;
+ }
+ else if (i < searchJunction)
+ {
+ // take whatever we took last time, look in address
+ if (address[ibyte] & ibit) a = 1;
+ else
+ {
+ // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s
+ a = 0;
+ done = 0;
+ lastJunction = i;
+ }
+ }
+ else
+ {
+ // we are blazing new tree, take the 0
+ a = 0;
+ searchJunction = i;
+ done = 0;
+ }
+ lastJunction = i;
+ }
+
+ if (a) address[ibyte] |= ibit;
+ else address[ibyte] &= ~ibit;
+
+ writeBit(a);
+ }
+
+ if (done) searchExhausted = true;
+
+ for (i = 0; i < 8; i++) newAddr[i] = address[i];
+
+ return 1;
+}
+
+// The 1-Wire CRC scheme is described in Maxim Application Note 27:
+// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
+//
+
+#if ONEWIRE_CRC8_TABLE
+// This table comes from Dallas sample code where it is freely reusable,
+// though Copyright (C) 2000 Dallas Semiconductor Corporation
+static BYTE dscrc_table[] =
+{
+ 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
+ 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
+ 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
+ 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
+ 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
+ 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
+ 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
+ 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
+ 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
+ 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
+ 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
+ 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
+ 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
+ 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
+ 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
+ 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
+
+//
+// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
+// and the registers. (note: this might better be done without the
+// table, it would probably be smaller and certainly fast enough
+// compared to all those delayMicrosecond() calls. But I got
+// confused, so I use this table from the examples.)
+//
+BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
+{
+ BYTE i;
+ BYTE crc = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ crc = dscrc_table[crc ^ addr[i] ];
+ }
+
+ return crc;
+}
+#else
+//
+// Compute a Dallas Semiconductor 8 bit CRC directly.
+//
+BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
+{
+ BYTE i, j;
+ BYTE crc = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ BYTE inbyte = addr[i];
+ for (j = 0; j < 8; j++)
+ {
+ BYTE mix = (crc ^ inbyte) & 0x01;
+ crc >>= 1;
+ if (mix) crc ^= 0x8C;
+ inbyte >>= 1;
+ }
+ }
+
+ return crc;
+}
+#endif
+
+static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
+
+//
+// Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
+// these, but here it is.
+//
+unsigned short OneWireCRC::crc16(unsigned short* data, unsigned short len)
+{
+ unsigned short i;
+ unsigned short crc = 0;
+
+ for ( i = 0; i < len; i++)
+ {
+ unsigned short cdata = data[len];
+
+ cdata = (cdata ^ (crc & 0xff)) & 0xff;
+ crc >>= 8;
+
+ if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
+
+ cdata <<= 6;
+ crc ^= cdata;
+ cdata <<= 1;
+ crc ^= cdata;
+ }
+
+ return crc;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWireCRC.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,138 @@
+/*
+* OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire
+* library. Please see additional copyrights below this one, including
+* references to other copyrights.
+*
+* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireCRC.
+*
+* OneWireCRC is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireCRC is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+Copyright (c) 2007, Jim Studt
+
+Updated to work with arduino-0008 and to include skip() as of
+2007/07/06. --RJL20
+
+Modified to calculate the 8-bit CRC directly, avoiding the need for
+the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
+-- Tom Pollard, Jan 23, 2008
+
+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.
+
+Much of the code was inspired by Derek Yerger's code, though I don't
+think much of that remains. In any event that was..
+ (copyleft) 2006 by Derek Yerger - Free to distribute freely.
+
+The CRC code was excerpted and inspired by the Dallas Semiconductor
+sample code bearing this copyright.
+*/
+//---------------------------------------------------------------------------
+// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
+//
+// 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 DALLAS SEMICONDUCTOR 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.
+//
+// Except as contained in this notice, the name of Dallas Semiconductor
+// shall not be used except as stated in the Dallas Semiconductor
+// Branding Policy.
+//--------------------------------------------------------------------------
+
+#ifndef SNATCH59_ONEWIRECRC_H
+#define SNATCH59_ONEWIRECRC_H
+
+#include <mbed.h>
+
+// Select the table-lookup method of computing the 8-bit CRC by setting this to 1
+#ifndef ONEWIRE_CRC8_TABLE
+#define ONEWIRE_CRC8_TABLE 1
+#endif
+
+typedef unsigned char BYTE; // used to be uint8_t : something a byte wide, whatever ....
+
+enum eSpeed {OVERDRIVE, STANDARD};
+
+class OneWireCRC
+{
+public:
+ OneWireCRC(PinName oneWire, eSpeed);
+
+ // reset, read, write functions
+ int reset();
+ void writeByte(int data);
+ int readByte();
+ int touchByte(int data);
+ void block(BYTE* data, int data_len);
+ int overdriveSkip(BYTE* data, int data_len);
+
+ // address functions
+ void matchROM(BYTE rom[8]);
+ void skipROM();
+
+ // address search functions
+ void resetSearch();
+ BYTE search(BYTE* newAddr);
+
+ // CRC check functions
+ static BYTE crc8(BYTE* addr, BYTE len);
+ static unsigned short crc16(unsigned short* data, unsigned short len);
+
+private:
+ const int* timing;
+
+ BYTE address[8];
+ int searchJunction; // so we can set to it -1 somewhere
+ bool searchExhausted;
+
+ DigitalInOut oneWirePort;
+
+ // read/write bit functions
+ void writeBit(int bit);
+ int readBit();
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWireDefs.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,66 @@
+/*
+* OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire
+* library.
+*
+* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireCRC.
+*
+* OneWireCRC is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireCRC is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SNATCH59_ONEWIREDEFS_H
+#define SNATCH59_ONEWIREDEFS_H
+
+// device ids
+#define DS18B20_ID 0x28
+#define DS18S20_ID 0x10
+
+#define ALARM_CONFIG_SIZE 3
+#define THERMOM_SCRATCHPAD_SIZE 9
+#define THERMOM_CRC_BYTE 8
+#define ADDRESS_SIZE 8
+#define ADDRESS_CRC_BYTE 7
+
+// One Wire command codes
+#define OVERDRIVE_SKIP 0x3C
+// ROM commands
+#define SEARCH_ROM 0xF0
+#define READ_ROM 0x33
+#define MATCH_ROM 0x55
+#define SKIP_ROM 0xCC
+#define ALARM_SEARCH 0xEC
+// Functions Commnds
+#define CONVERT 0x44
+#define WRITESCRATCH 0x4E
+#define READSCRATCH 0xBE
+#define COPYSCRATCH 0x48
+#define RECALLE2 0xB8
+#define READPOWERSUPPLY 0xB4
+
+// temperature read resolutions
+enum eResolution {nineBit = 0, tenBit, elevenBit, twelveBit};
+const int CONVERSION_TIME[] = {94, 188, 375, 750}; // milli-seconds
+
+// DS18B20/DS18S20 related
+#define TEMPERATURE_LSB 0
+#define TEMPERATURE_MSB 1
+#define HIGH_ALARM_BYTE 2
+#define LOW_ALARM_BYTE 3
+#define CONFIG_REG_BYTE 4
+#define CONFIG_READ_END 5
+#define COUNT_REMAIN_BYTE 6
+#define COUNT_PER_DEG_BYTE 7
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWireThermometer.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,167 @@
+/*
+* OneWireThermometer. Base class for Maxim One-Wire Thermometers.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "OneWireThermometer.h"
+#include "OneWireDefs.h"
+#include "DebugTrace.h"
+
+DebugTrace pc2(ON, TO_SERIAL);
+
+// constructor specifies standard speed for the 1-Wire comms
+OneWireThermometer::OneWireThermometer(bool crcOn, bool useAddr, bool parasitic, PinName pin, int device_id) :
+ useCRC(crcOn), useAddress(useAddr), useParasiticPower(parasitic),
+ oneWire(pin, STANDARD), deviceId(device_id), resolution(twelveBit)
+{
+ // NOTE: the power-up resolution of a DS18B20 is 12 bits. The DS18S20's resolution is always
+ // 9 bits + enhancement, but we treat the DS18S20 as fixed to 12 bits for calculating the
+ // conversion time Tconv.
+}
+
+bool OneWireThermometer::initialize()
+{
+ // get the device address for use in selectROM() when reading the temperature
+ // - not really needed except for device validation if using skipROM()
+ if (useAddress)
+ {
+ pc2.traceOut("\r\n");
+ pc2.traceOut("New Scan\r\n");
+
+ oneWire.resetSearch();
+ if (!oneWire.search(address)) // search for 1-wire device address
+ {
+ pc2.traceOut("No more addresses.\r\n");
+ wait(2);
+ return false;
+ }
+
+ pc2.traceOut("Address = ");
+ for (int i = 0; i < ADDRESS_SIZE; i++)
+ {
+ pc2.traceOut("%x ", (int)address[i]);
+ }
+ pc2.traceOut("\r\n");
+
+ if (OneWireCRC::crc8(address, ADDRESS_CRC_BYTE) != address[ADDRESS_CRC_BYTE]) // check address CRC is valid
+ {
+ pc2.traceOut("CRC is not valid!\r\n");
+ wait(2);
+ return false;
+ }
+
+ if (address[0] != deviceId)
+ {
+ // Make sure it is a one-wire thermometer device
+ if (DS18B20_ID == deviceId)
+ pc2.traceOut("You need to use a DS1820 or DS18S20 for correct results.\r\n");
+ else if (DS18S20_ID == deviceId)
+ pc2.traceOut("You need to use a DS18B20 for correct results.\r\n");
+ else
+ pc2.traceOut("Device is not a DS18B20/DS1820/DS18S20 device.\r\n");
+
+ wait(2);
+ return false;
+ }
+ else
+ {
+ if (DS18B20_ID == deviceId) pc2.traceOut("DS18B20 present and correct.\r\n");
+ if (DS18S20_ID == deviceId) pc2.traceOut("DS1820/DS18S20 present and correct.\r\n");
+ }
+ }
+
+ return true;
+}
+
+// NOTE ON USING SKIP ROM: ok to use before a Convert command to get all
+// devices on the bus to do simultaneous temperature conversions. BUT can
+// only use before a Read Scratchpad command if there is only one device on the
+// bus. For purpose of this library it is assumed there is only one device
+// on the bus.
+void OneWireThermometer::resetAndAddress()
+{
+ oneWire.reset(); // reset device
+ if (useAddress)
+ {
+ oneWire.matchROM(address); // select which device to talk to
+ }
+ else
+ {
+ oneWire.skipROM(); // broadcast
+ }
+}
+
+bool OneWireThermometer::readAndValidateData(BYTE* data)
+{
+ bool dataOk = true;
+
+ resetAndAddress();
+ oneWire.writeByte(READSCRATCH); // read Scratchpad
+
+ pc2.traceOut("read = ");
+ for (int i = 0; i < THERMOM_SCRATCHPAD_SIZE; i++)
+ {
+ // we need all bytes which includes CRC check byte
+ data[i] = oneWire.readByte();
+ pc2.traceOut("%x ", (int)data[i]);
+ }
+ pc2.traceOut("\r\n");
+
+ // Check CRC is valid if you want to
+ if (useCRC && !(OneWireCRC::crc8(data, THERMOM_CRC_BYTE) == data[THERMOM_CRC_BYTE]))
+ {
+ // CRC failed
+ pc2.traceOut("CRC FAILED... \r\n");
+ dataOk = false;
+ }
+
+ return dataOk;
+}
+
+float OneWireThermometer::readTemperature()
+{
+ BYTE data[THERMOM_SCRATCHPAD_SIZE];
+ float realTemp = -999;
+
+ resetAndAddress();
+ oneWire.writeByte(CONVERT); // issue Convert command
+
+ if (useParasiticPower)
+ {
+ // wait while converting - Tconv (according to resolution of reading)
+ wait_ms(CONVERSION_TIME[resolution]);
+ }
+ else
+ {
+ // TODO
+ // after the Convert command, the device should respond by transmitting 0
+ // while the temperature conversion is in progress and 1 when the conversion is done
+ // - as were are not checking this (TODO), we use Tconv, as we would do for
+ // parasitic power
+ wait_ms(CONVERSION_TIME[resolution]);
+ }
+
+ if (readAndValidateData(data)) // issue Read Scratchpad commmand and get data
+ {
+ realTemp = calculateTemperature(data);
+ }
+
+ return realTemp;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWireThermometer.h Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,57 @@
+/*
+* OneWireThermometer. Base class for Maxim One-Wire Thermometers.
+* Uses the OneWireCRC library.
+*
+* Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
+*
+* This file is part of OneWireThermometer.
+*
+* OneWireThermometer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* OneWireThermometer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SNATCH59_ONEWIRETHERMOMETER_H
+#define SNATCH59_ONEWIRETHERMOMETER_H
+
+#include <mbed.h>
+#include "OneWireCRC.h"
+#include "OneWireDefs.h"
+
+typedef unsigned char BYTE; // something a byte wide
+
+class OneWireThermometer
+{
+public:
+ OneWireThermometer(bool crcOn, bool useAddr, bool parasitic, PinName pin, int device_id);
+
+ bool initialize();
+ float readTemperature();
+ virtual void setResolution(eResolution resln) = 0;
+
+protected:
+ const bool useParasiticPower;
+ const bool useCRC;
+ const bool useAddress;
+ const int deviceId;
+
+ eResolution resolution;
+ BYTE address[8];
+
+ OneWireCRC oneWire;
+
+ void resetAndAddress();
+ bool readAndValidateData(BYTE* data);
+ virtual float calculateTemperature(BYTE* data) = 0; // device specific
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/TextLCD/#1c0232c55749
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Nov 10 22:56:20 2014 +0000
@@ -0,0 +1,516 @@
+#include "mbed.h"
+#include "BridgeDriver.h"
+#include "FrontPanelButtons.h"
+#include "SDFileSystem.h"
+#include "LocalPinNames.h"
+#include "TextLCD.h"
+#include "max31855.h"
+#include <string>
+#include <stdio.h>
+using std::string;
+
+#include "DS18S20.h"
+#include "DS18B20.h"
+#include "OneWireDefs.h"
+
+#define THERMOMETER DS18B20
+// device( crcOn, useAddress, parasitic, mbed pin )
+THERMOMETER device(true, true, false, p25);
+
+Serial pc(USBTX, USBRX);
+
+Timer timer; // general purpose timer
+I2C i2c( P0_10, P0_11 ); // I2C bus (SDA, SCL)
+//TextLCD_I2C lcd( &i2c, MCP23008_SA0, TextLCD::lcd20x4 ); // lcd
+FrontPanelButtons buttons( &i2c ); // front panel buttons
+
+Timer debounceTimer;
+Timer avgCycTimer;
+
+DigitalIn signal(DIO0, PullUp);
+CAN can(p9, p10);
+
+//SPI Interfaces
+SPI testSPI(P0_9, P0_8, P0_7); // mosi(out), miso(in), sclk(clock) //SPI Bus
+//SPI testSPI(P0_9, DIO3, DIO1); // mosi(out), miso(in), sclk(clock) //SPI Bus
+
+
+CANMessage readBuffer;
+int numBuffMsg = 0;
+
+float totaltime = 0;
+int cycleCount = 1;
+int numCycles = 1000;
+
+float currTemp = 0; //Float value to hold temperature returned
+
+//Function Definitions
+void waitSwitch(char [], int);
+void waitSwitchRelease(char [], int);
+void waitLatch(char [], int);
+int checkLatchStatus();
+float getTemp();
+
+
+/******************************************************************************/
+/************ CAN Commands *************/
+/******************************************************************************/
+
+void openDoorCommand(char dataBytes[]){
+ dataBytes[3] = 0x03;
+ can.write(CANMessage(534, dataBytes, 4)); // open the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+}
+
+void closeDoorCommand(char dataBytes[]){
+ dataBytes[3] = 0x02;
+ can.write(CANMessage(534, dataBytes, 4)); // close the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+}
+
+/******************************************************************************/
+/************ Receieve *************/
+/******************************************************************************/
+
+void receive(){
+ CANMessage msg;
+ if (can.read(msg)){
+ if (msg.id == 534){
+ readBuffer = msg;
+ numBuffMsg = 1;
+ }
+ }
+}
+
+
+/******************************************************************************/
+/************ Full Init *************/
+/******************************************************************************/
+
+void fullInit(){
+// i2c.frequency(1000000);
+// lcd.setBacklight(TextLCD::LightOn);
+// wait(.6);
+// lcd.cls(); //clear the display
+
+ can.frequency(500000);
+ can.attach(&receive, CAN::RxIrq);
+
+
+ //********* Init the Thermocouple **********//
+
+ while (!device.initialize()); // keep calling until it works
+
+ device.setResolution(nineBit);
+}
+
+
+/******************************************************************************/
+/************ waitSwitch *************/
+/******************************************************************************/
+
+void waitSwitch(char dataBytes[], int openTimeout){
+
+ int openComplete = 0;
+ while (!openComplete){
+
+ openDoorCommand(dataBytes); //send CAN message to open the door
+
+ timer.reset();
+ timer.start();
+ int flag = 0;
+ while (!flag){
+ if (signal.read() == 0){
+ while (!flag){
+ debounceTimer.reset();
+ debounceTimer.start();
+ while (debounceTimer.read_ms() < 40);
+ if ( signal.read() == 0){
+ flag = 1;
+ openComplete = 1;
+ }
+ }
+ }
+ else if (timer.read() >= openTimeout)
+ flag = 1;
+ }
+
+ timer.stop();
+
+ // timeout on opening
+ if (timer.read() >= openTimeout){
+
+ avgCycTimer.stop(); //pause
+
+ dataBytes[3] = 0x01;
+ can.write(CANMessage(534, dataBytes, 4)); // stop the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+
+ //Error Message
+// pc.setAddress ( 0, 1 );
+ pc.printf( "<Press Button to Resume>\r\n" );
+// pc.setAddress( 0, 2 );
+ pc.printf( "ERROR Open Timeout\r\n" );
+
+ while (!buttons.readSel()); //Do nothing until the button is selected
+
+ avgCycTimer.start(); //start
+
+ //Remove Error Message
+// pc.cls(); //clear the display
+
+// pc.setAddress( 0, 0 );
+ pc.printf( "Cycle %d of %3d\r\n", cycleCount, numCycles );
+// pc.setAddress( 0, 1 );
+ pc.printf( "Avg t(sec): %1.3f\r\n", (totaltime / cycleCount));
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: OPENING\r\n");
+ }
+ }
+}
+
+
+/******************************************************************************/
+/************ Close Door / Switch Release *************/
+/******************************************************************************/
+
+void waitSwitchRelease(char dataBytes[], int switchReleaseTimeout){
+
+ int switchReleaseComplete = 0;
+ while (!switchReleaseComplete){
+
+ closeDoorCommand(dataBytes); //send CAN message to close the door
+
+ timer.reset();
+ timer.start();
+ int flag = 0;
+ while (!flag){
+ if (signal.read() == 1){
+ while (!flag){
+ debounceTimer.reset();
+ debounceTimer.start();
+ while (debounceTimer.read_ms() < 40);
+ if ( signal.read() == 1){
+ flag = 1;
+ switchReleaseComplete = 1;
+ }
+ }
+ }
+ else if (timer.read() >= switchReleaseTimeout)
+ flag = 1;
+ }
+
+ timer.stop();
+
+ // timeout on switch release
+ if (timer.read() >= switchReleaseTimeout){
+
+ avgCycTimer.stop(); //pause
+
+ dataBytes[3] = 0x01;
+ can.write(CANMessage(534, dataBytes, 4)); // stop the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+
+ //Error Message
+// pc.setAddress ( 0, 1 );
+ pc.printf( "<Press Sel to Resume>\r\n" );
+// pc.setAddress( 0, 2 );
+ pc.printf( "ERROR Release Switch Timeout\r\n" );
+
+ while (!buttons.readSel()); //Do nothing until the button is selected
+
+ avgCycTimer.start(); //start
+
+ //Remove Error Message
+// pc.cls(); //clear the display
+
+// pc.setAddress( 0, 0 );
+ pc.printf( "Cycle %d of %3d\r\n", cycleCount, numCycles );
+// pc.setAddress( 0, 1 );
+ pc.printf( "Avg t(sec): %1.3f\r\n", (totaltime / cycleCount));
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: SWITCH\r\n");
+ }
+ }
+}
+
+
+/******************************************************************************/
+/************ Close Door to Latch *************/
+/******************************************************************************/
+
+void waitLatch(char dataBytes[], int closeTimeout){
+
+ //Loop through the close sequence until the latch is closed
+ int closeComplete = 0;
+ while (!closeComplete){
+
+ closeDoorCommand(dataBytes); //send CAN message to close the door
+
+ timer.reset();
+ timer.start();
+ int flag = 0;
+ while (!flag){
+
+ if (checkLatchStatus()){
+ flag = 1;
+ closeComplete = 1;
+ }
+
+ //if the timer goes off
+ else if (timer.read() >= closeTimeout)
+ flag = 1;
+ }
+
+ timer.stop();
+
+ // timeout on closing
+ if (timer.read() >= closeTimeout){
+
+ avgCycTimer.stop(); //pause
+
+ //Error Message
+// pc.setAddress ( 0, 1 );
+ pc.printf( "<Press Sel to Resume>\r\n" );
+// pc.setAddress( 0, 2 );
+ pc.printf( "ERROR Close Timeout\r\n" );
+
+ dataBytes[3] = 0x01;
+ can.write(CANMessage(534, dataBytes, 4)); // stop the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+
+ while (!buttons.readSel()); //Do nothing until the button is selected
+
+ avgCycTimer.start(); //start
+
+ //Remove Error Message
+// pc.cls(); //clear the display
+
+// pc.setAddress( 0, 0 );
+ pc.printf( "Cycle %d of %3d\r\n", cycleCount, numCycles );
+// pc.setAddress( 0, 1 );
+ pc.printf( "Avg t(sec): %1.3f\r\n", (totaltime / cycleCount));
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: CLOSING\r\n");
+ }
+ }
+}
+
+
+/******************************************************************************/
+/************ Check Latch Status *************/
+/******************************************************************************/
+
+// Returns 1 if latch is closed, 0 if it is not closed
+int checkLatchStatus(){
+
+ //convert the data array into a single 64 bit value so that we can grab the range of bits we desire, no matter where they're located
+ long long allData = 0;
+ for (int j = 0; j < 8; j++){
+ long long tempData1 = (long long)readBuffer.data[j];
+ tempData1 <<= (8 * j); //shift data bits into there proper position in the 64 bit long long
+ allData |= tempData1;
+ }
+
+ int _startBitValue = 4, _numBitsValue = 4; //get the latch status bits
+ //isolate the desired range of bits for comparison
+ // (_numBitsValue - 1) makes it so the following, startBit = 13, numBites = 5 would mean you want up to bit 17, but (13 + 5) brings you to 18, therefore do (numBits - 1)
+ int compareBits = (allData >> _startBitValue) & ~(~0 << ((_startBitValue+(_numBitsValue-1))-_startBitValue+1));
+
+ int compareValue = 0; //value to watch (i.e. 0 for latch closed)
+
+ //if the latch is closed
+ if (compareBits == compareValue)
+ return 1;
+
+ return 0;
+}
+
+
+/******************************************************************************/
+/************ getTemp *************/
+/******************************************************************************/
+
+float getTemp(){
+
+ return device.readTemperature();
+}
+
+/******************************************************************************/
+/************ Main *************/
+/******************************************************************************/
+
+int main() {
+
+ fullInit();
+
+ int openTimeout = 10; //10sec timeout
+ int switchReleaseTimeout = 2;
+ int closeTimeout = 10;
+
+ char dataBytes[4];
+ dataBytes[0] = 0x00;
+ dataBytes[1] = 0x00;
+ dataBytes[2] = 0x00;
+
+
+// pc.setAddress ( 0, 3 );
+ pc.printf( "<Press Button to start>\r\n" );
+
+
+// while (!buttons.readSel()){
+// if(buttons.readUp() && numCycles < 999999 ){
+// numCycles = numCycles + 100;
+// wait(0.2);
+// }
+// else if (buttons.readDown() && numCycles > 0 ){
+// numCycles = numCycles - 100;
+// wait(0.2);
+// }
+// pc.setAddress ( 0, 0 );
+// pc.printf( "<Num Cycles:%5d >" , numCycles );
+// }
+
+// pc.cls(); //clear the display
+
+// while(1){
+// currTemp = getTemp();
+// printf("%f",currTemp);
+// wait(1);
+// }
+
+/******************************************************************************/
+/************ Cycle Loop *************/
+/******************************************************************************/
+
+ while (cycleCount <= numCycles){
+
+// pc.setAddress( 0, 0 );
+ pc.printf( "Cycle %d of %3d\r\n", cycleCount, numCycles );
+ avgCycTimer.reset();
+ avgCycTimer.start();
+
+
+/******************************************************************************/
+/************ Open *************/
+/******************************************************************************/
+
+ openDoorCommand(dataBytes);
+
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: OPENING\r\n");
+
+ waitSwitch(dataBytes, openTimeout);
+
+/******************************************************************************/
+/************ waitSwitchRelease *************/
+/******************************************************************************/
+
+ closeDoorCommand(dataBytes);
+
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: SWITCH\r\n");
+
+ waitSwitchRelease(dataBytes, switchReleaseTimeout);
+
+/******************************************************************************/
+/************ waitSwitchRelease *************/
+/******************************************************************************/
+
+// pc.setAddress( 0, 2 );
+ pc.printf( "STATUS: CLOSING\r\n");
+
+ waitLatch(dataBytes, closeTimeout);
+
+/******************************************************************************/
+/************ End Cycle *************/
+/******************************************************************************/
+
+ totaltime += avgCycTimer.read();
+// pc.setAddress( 0, 1 );
+ pc.printf( "Avg t(sec): %1.3f\r\n", (totaltime / cycleCount));
+ wait(0.2);
+ cycleCount++;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /*
+ pc.setAddress ( 0, 0 );
+ pc.printf( "^ Up = Open" );
+ pc.setAddress ( 0, 1 );
+ pc.printf( "v Down = Close" );
+ pc.setAddress ( 0, 2 );
+ pc.printf( "> Right = Stop" );
+
+ while(1){
+ if (buttons.readUp()){
+ dataBytes[3] = 0x03;
+ can.write(CANMessage(534, dataBytes, 4)); // open the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+ }
+ else if (buttons.readDown()){
+ dataBytes[3] = 0x02;
+ can.write(CANMessage(534, dataBytes, 4)); // close the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+ }
+ else if (buttons.readRight()){
+ dataBytes[3] = 0x01;
+ can.write(CANMessage(534, dataBytes, 4)); // stop the door
+ wait(0.1);
+ dataBytes[3] = 0x00;
+ can.write(CANMessage(534, dataBytes, 4)); // Set to IDLE
+ }
+ }*/
+ /*
+ while (1){
+ //convert the data array into a single 64 bit value so that we can grab the range of bits we desire, no matter where they're located
+ long long allData = 0; //((long long)*readMsg[k].data);
+ for (int j = 0; j < 8; j++){
+ long long tempData1 = (long long)readBuffer.data[j];
+ tempData1 <<= (8 * j); //shift data bits into there proper position in the 64 bit long long
+ allData |= tempData1;
+ }
+
+ int _startBitValue = 4, _numBitsValue = 4; //get the latch status bits
+ //isolate the desired range of bits for comparison
+ // (_numBitsValue - 1) makes it so the following, startBit = 13, numBites = 5 would mean you want up to bit 17, but (13 + 5) brings you to 18, therefore do (numBits - 1)
+ int compareBits = (allData >> _startBitValue) & ~(~0 << ((_startBitValue+(_numBitsValue-1))-_startBitValue+1));
+
+ int compareValue = 0; //value to watch (i.e. 0 for latch closed)
+ //if the latch is closed
+ if (compareBits == compareValue){
+ pc.setAddress ( 0, 0 );
+ pc.printf( "Latch: Closed " );
+ }
+ else{
+ pc.setAddress ( 0, 0 );
+ pc.printf( "Latch: Not Closed " );
+ }
+ }*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Nov 10 22:56:20 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89 \ No newline at end of file