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