From 22a5b466db8f5f48d61390a4c1be4979d83120dc Mon Sep 17 00:00:00 2001 From: Tristan Krause Date: Fri, 7 Jun 2019 11:02:46 +0200 Subject: [PATCH] leeres plottyfile wirft exception --- control/examples/diode/main.cpp | 1 + control/examples/pegel/main.cpp | 5 + control/src/drv/b15f.h | 2 +- control/src/drv/b15f.h.orig | 280 ++++++++++++++++++++++++++++ control/src/drv/plottyfile.cpp | 3 + control/src/drv/plottyfile.cpp.orig | 201 ++++++++++++++++++++ control/src/drv/plottyfile.h | 1 + 7 files changed, 492 insertions(+), 1 deletion(-) create mode 100644 control/src/drv/b15f.h.orig create mode 100644 control/src/drv/plottyfile.cpp.orig diff --git a/control/examples/diode/main.cpp b/control/examples/diode/main.cpp index 694664d..1e96a1b 100644 --- a/control/examples/diode/main.cpp +++ b/control/examples/diode/main.cpp @@ -103,6 +103,7 @@ void kennlinieZweiterQuadrant() if(ba[k] > bb[k] && bb[k] % 50 == 0 && bb[k] != 0) { uint16_t i_d = ba[k] - bb[k]; + std::cout << "added" << std::endl; pf.addDot(Dot(u_gs, i_d, bb[k] / 50)); } curve++; diff --git a/control/examples/pegel/main.cpp b/control/examples/pegel/main.cpp index b2624fd..e216b02 100644 --- a/control/examples/pegel/main.cpp +++ b/control/examples/pegel/main.cpp @@ -3,6 +3,11 @@ #include #include +/* + * Inkrementiert DAC 0 von 0 bis 1023 und speichert zu jeder Ausgabe den Wert von ADC 0 in einem Puffer. + * Die Funktion ADC 0 abhängig von DAC 0 wird als Graph geplottet. + */ + const char PLOT_FILE[] = "plot.bin"; int main() diff --git a/control/src/drv/b15f.h b/control/src/drv/b15f.h index b708e3e..9eb8e35 100644 --- a/control/src/drv/b15f.h +++ b/control/src/drv/b15f.h @@ -202,7 +202,7 @@ public: /** * Setzt die Register so, dass näherungsweise die gewünschte Frequenz erzeugt wird. * Ist freq == 0 wird PWM deaktiviert. - * Standardfrequenz: 31300 (empfohlen, da dann TOP == 255) + * Standardfrequenz: 31300 (empfohlen, da dann TOP == 255) * \param freq PWM Frequenz * \return Top Wert des PWM Value für die gesetzte Frequenz * \throws DriverException diff --git a/control/src/drv/b15f.h.orig b/control/src/drv/b15f.h.orig new file mode 100644 index 0000000..b708e3e --- /dev/null +++ b/control/src/drv/b15f.h.orig @@ -0,0 +1,280 @@ +#ifndef B15F_H +#define B15F_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "usart.h" +#include "driverexception.h" +#include "timeoutexception.h" + +// wichtig für die Register-Zugriffe +#define _AVR_IO_H_ 1 // Erzwinge die Inklusion +#include "/usr/lib/avr/include/avr/sfr_defs.h" +#include "/usr/lib/avr/include/avr/iom1284p.h" + +typedef std::function errorhandler_t; + + +/*! main driver class */ + +class B15F +{ +private: + // privater Konstruktor + B15F(void); +public: + + /************************************* + * Grundfunktionen des B15F Treibers * + *************************************/ + + /** + * Versucht die Verbindung zum B15 wiederherzustellen + * \throws DriverException + */ + void reconnect(void); + + /** + * Verwirft Daten im USART Puffer auf dieser Maschine und B15 + * \throws DriverException + */ + void discard(void); + + /** + * Testet die USART Verbindung auf Funktion + * \throws DriverException + */ + bool testConnection(void); + + /** + * Testet die Integer Konvertierung der USART Verbindung + * \throws DriverException + */ + bool testIntConv(void); + + /** + * Liefert Informationen zur aktuellen Firmware des B15 + * \throws DriverException + */ + std::vector getBoardInfo(void); + + /** + * Lässt den Treiber für eine angegebene Zeit pausieren + * \param ms Verzögerung in Millisekunden + */ + void delay_ms(uint16_t ms); + + /** + * Lässt den Treiber für eine angegebene Zeit pausieren + * \param us Verzögerung in Microsekunden + */ + void delay_us(uint16_t us); + + /** + * Liefert eine Referenz zur aktuellen Treiber-Instanz + * @throws DriverException + */ + static B15F& getInstance(void); + + /** + * Führt ein Befehl auf dieser Maschine aus und liefert stdout zurück + * \param cmd Der Befehl + */ + static std::string exec(std::string cmd); + + /** + * Multithread sicherer Abbruch des B15F-Treibers + * \param msg Beschreibung der Abbruchursache + */ + static void abort(std::string msg); + + /** + * Multithread sicherer Abbruch des B15F-Treibers + * \param ex Exception als Abbruchursache + */ + static void abort(std::exception& ex); + + /** + * Setzt eine Fehlerbehandlungsroutine für den Treiberabbruch (abort) + * \param func Funktion, die Exception als Parameter bekommt + */ + static void setAbortHandler(errorhandler_t func); + + /*************************************/ + + + + /************************* + * Steuerbefehle für B15 * + *************************/ + + /** + * Versetzt das Board in den Selbsttest-Modus + * WICHTIG: Es darf dabei nichts an den Klemmen angeschlossen sein! + * \throws DriverException + */ + bool activateSelfTestMode(void); + + /** + * Setzt den Wert des digitalen Ausgabeports 0 + * \param port Wert für gesamten Port + * \throws DriverException + */ + bool digitalWrite0(uint8_t); + + /** + * Setzt den Wert des digitalen Ausgabeports 1 + * \param port Wert für gesamten Port + * \throws DriverException + */ + bool digitalWrite1(uint8_t); + + /** + * Liest den Wert des digitalen Eingabeports 0 + * \return Wert für gesamten Port + * \throws DriverException + */ + uint8_t digitalRead0(void); + + /** + * Liest den Wert des digitalen Eingabeports 1 + * \return Wert für gesamten Port + * \throws DriverException + */ + uint8_t digitalRead1(void); + + /** + * Liest den Wert des digitalen Eingabeports, an dem der DIP-switch angeschlossen ist (S7) + * \return Wert für gesamten Port + * \throws DriverException + */ + uint8_t readDipSwitch(void); + + /** + * Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 0 + * \param port 10-Bit Wert + * \throws DriverException + */ + bool analogWrite0(uint16_t port); + + /** + * Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 1 + * \param port 10-Bit Wert + * \throws DriverException + */ + bool analogWrite1(uint16_t port); + + /** + * Liest den Wert des Analog-Digital-Converters (ADC / ADU) + * \param channel Kanalwahl von 0 - 7 + * \throws DriverException + */ + uint16_t analogRead(uint8_t channel); + + /** + * DAC 0 wird auf den Startwert gesetzt und dann schrittweise um Delta inkrementiert. + * Für jeden eingestelleten DAC-Wert werden zwei ADCs (channel_a und channel_b) angesprochen und die Werte übermittelt. + * Die Werte werden in buffer_a für Kanal a und buffer_b für Kanal b gespeichert. + * \param channel_a Auswahl des ADC a, von 0 - 7 + * \param buffer_a Speichertort für Werte des Kanals a + * \param offset_a Anzahl an Werten des Kanals a, die im Speicher übersprungen werden sollen + * \param channel_b Auswahl des ADC b, von 0 - 7 + * \param buffer_b Speichertort für Werte des Kanals b + * \param offset_b Anzahl an Werten des Kanals b, die im Speicher übersprungen werden + * \param start Startwert des DACs + * \param delta Schrittweite, mit welcher der DAC inkrementiert wird + * \param count Anzahl an Inkrementierungen + * \throws DriverException + */ + void analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count); + + /** + * Setzt die Register so, dass näherungsweise die gewünschte Frequenz erzeugt wird. + * Ist freq == 0 wird PWM deaktiviert. + * Standardfrequenz: 31300 (empfohlen, da dann TOP == 255) + * \param freq PWM Frequenz + * \return Top Wert des PWM Value für die gesetzte Frequenz + * \throws DriverException + */ + uint8_t pwmSetFrequency(uint32_t freq); + + /** + * Setzt den PWM Wert. + * \param value PWM Wert [0..0xFF] + * \throws DriverException + */ + bool pwmSetValue(uint8_t value); + + /** + * Setzt direkt den Wert eines MCU Registers. + * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! + * \param adr Speicheradresse des Registers + * \param val Neuer Wert für das Register + * \throws DriverException + */ + bool setRegister(volatile uint8_t* adr, uint8_t val); + + /** + * Liefert den Wert eines MCU Registers. + * \param adr Speicheradresse des Registers + * \throws DriverException + */ + uint8_t getRegister(volatile uint8_t* adr); + + /*************************/ + + + // CONSTANTS + const std::string PRE = "[B15F] "; //!< B15F stdout prefix + constexpr static uint8_t MSG_OK = 0xFF; //!< Value to acknowledge a received command + constexpr static uint8_t MSG_FAIL = 0xFE; //!< Value to reject a received command + constexpr static uint16_t RECONNECT_TIMEOUT = 64; //!< Time in ms after which a reconnect attempt aborts + constexpr static uint16_t WDT_TIMEOUT = 15; //!< Time in ms after which the watch dog timer resets the MCU + constexpr static uint8_t RECONNECT_TRIES = 3; //!< Maximum count of reconnect attempts after which the driver stops + constexpr static uint32_t BAUDRATE = 57600; //!< USART baudrate for communication with the MCU + +private: + + /** + * Initialisiert und testet die Verbindung zum B15 + * \throws DriverException + */ + void init(void); + + USART usart; + static B15F* instance; + static errorhandler_t errorhandler; + + // REQUESTS + constexpr static uint8_t RQ_DISC = 0; + constexpr static uint8_t RQ_TEST = 1; + constexpr static uint8_t RQ_INFO = 2; + constexpr static uint8_t RQ_INT = 3; + constexpr static uint8_t RQ_ST = 4; + constexpr static uint8_t RQ_BA0 = 5; + constexpr static uint8_t RQ_BA1 = 6; + constexpr static uint8_t RQ_BE0 = 7; + constexpr static uint8_t RQ_BE1 = 8; + constexpr static uint8_t RQ_DSW = 9; + constexpr static uint8_t RQ_AA0 = 10; + constexpr static uint8_t RQ_AA1 = 11; + constexpr static uint8_t RQ_ADC = 12; + constexpr static uint8_t RQ_ADC_DAC_STROKE = 13; + constexpr static uint8_t RQ_PWM_SET_FREQ = 14; + constexpr static uint8_t RQ_PWM_SET_VALUE = 15; + constexpr static uint8_t RQ_SET_REG = 16; + constexpr static uint8_t RQ_GET_REG = 17; +}; + +#endif // B15F_H diff --git a/control/src/drv/plottyfile.cpp b/control/src/drv/plottyfile.cpp index c236531..f426fb4 100644 --- a/control/src/drv/plottyfile.cpp +++ b/control/src/drv/plottyfile.cpp @@ -146,6 +146,9 @@ void PlottyFile::prepStr(std::string& str, uint8_t len) void PlottyFile::writeToFile(std::string filename) { + if(dots.empty()) + throw std::length_error("Es wurden keine Punkte gespeichert."); + prepStr(unit_x, STR_LEN_SHORT); prepStr(desc_x, STR_LEN_LARGE); prepStr(unit_y, STR_LEN_SHORT); diff --git a/control/src/drv/plottyfile.cpp.orig b/control/src/drv/plottyfile.cpp.orig new file mode 100644 index 0000000..355abb8 --- /dev/null +++ b/control/src/drv/plottyfile.cpp.orig @@ -0,0 +1,201 @@ +#include "plottyfile.h" + +void PlottyFile::addDot(Dot& dot) +{ + dots.push_back(dot); +} + +void PlottyFile::addDot(Dot dot) +{ + dots.push_back(dot); +} + +void PlottyFile::setFunctionType(FunctionType function_type) +{ + this->function_type = function_type; +} + +void PlottyFile::setQuadrant(uint8_t quadrant) +{ + if(quadrant < 1 || quadrant > 4) + throw std::range_error("Ungueltiger Quadrant"); + this->quadrant = quadrant; +} + +void PlottyFile::setRefX(uint16_t ref_x) +{ + this->ref_x = ref_x; +} + +void PlottyFile::setRefY(uint16_t ref_y) +{ + this->ref_y = ref_y; +} + +void PlottyFile::setParaFirstCurve(uint16_t para_first) +{ + this->para_first = para_first; +} + +void PlottyFile::setParaStepWidth(uint16_t para_stepwidth) +{ + this->para_stepwidth = para_stepwidth; +} + +void PlottyFile::setUnitX(std::string unit_x) +{ + this->unit_x = unit_x; +} + +void PlottyFile::setDescX(std::string desc_x) +{ + this->desc_x = desc_x; +} + +void PlottyFile::setUnitY(std::string unit_y) +{ + this->unit_y = unit_y; +} + +void PlottyFile::setDescY(std::string desc_y) +{ + this->desc_y = desc_y; +} + +void PlottyFile::setUnitPara(std::string unit_para) +{ + this->unit_para = unit_para; +} + +void PlottyFile::setDescPara(std::string desc_para) +{ + this->desc_para = desc_para; +} + +FunctionType PlottyFile::getFunctionType() const +{ + return function_type; +} + +uint8_t PlottyFile::getQuadrant() const +{ + return quadrant; +} + +uint16_t PlottyFile::getRefX() const +{ + return ref_x; +} + +uint16_t PlottyFile::getRefY() const +{ + return ref_y; +} + +uint16_t PlottyFile::getParaFirstCurve() const +{ + return para_first; +} + +uint16_t PlottyFile::getParaStepWidth() const +{ + return para_stepwidth; +} + +std::string PlottyFile::getUnitX() const +{ + return unit_x; +} + +std::string PlottyFile::getDescX() const +{ + return desc_x; +} + +std::string PlottyFile::getUnitY() const +{ + return unit_y; +} + +std::string PlottyFile::getDescY() const +{ + return desc_y; +} + +std::string PlottyFile::getUnitPara() const +{ + return unit_para; +} + +std::string PlottyFile::getDescPara() const +{ + return desc_para; +} + +void PlottyFile::prepStr(std::string& str, uint8_t len) +{ + if(str.length() > len) + throw std::runtime_error("Zu grosser String."); + + if(str.length() != len) + str += '\n'; + + while(str.length() < len) + str += '\0'; +} + +void PlottyFile::writeToFile(std::string filename) +{ + if(dots.empty()) + throw std::length_error("Es wurden keine Punkte gespeichert."); + + prepStr(unit_x, STR_LEN_SHORT); + prepStr(desc_x, STR_LEN_LARGE); + prepStr(unit_y, STR_LEN_SHORT); + prepStr(desc_y, STR_LEN_LARGE); + prepStr(unit_para, STR_LEN_SHORT); + prepStr(desc_para, STR_LEN_LARGE); + + std::ofstream file(filename); + + // write file header + file.write(reinterpret_cast(&command), 1); + file.write(head.c_str(), head.length()); + file.write(filetype.c_str(), filetype.length()); + file.write(reinterpret_cast(&version), 2); + file.write(reinterpret_cast(&subversion), 2); + file.put(static_cast(function_type)); + file.write(reinterpret_cast(&quadrant), 1); + file.write(reinterpret_cast(&ref_x), 2); + file.write(reinterpret_cast(&ref_y), 2); + file.write(reinterpret_cast(¶_first), 2); + file.write(reinterpret_cast(¶_stepwidth), 2); + file.write(unit_x.c_str(), unit_x.length()); + file.write(desc_x.c_str(), desc_x.length()); + file.write(unit_y.c_str(), unit_y.length()); + file.write(desc_y.c_str(), desc_y.length()); + file.write(unit_para.c_str(), unit_para.length()); + file.write(desc_para.c_str(), desc_para.length()); + file.write(reinterpret_cast(&eof), 1); + + // make sure header size is 256 Byte + while(file.tellp() < 256) + file.put(0); + + for(Dot& dot : dots) + { + file.put((dot.getX() >> 8) | (static_cast(dot.getCurve()) << 2)); + file.put(dot.getX() & 0xFF); + file.put(dot.getY() >> 8); + file.put(dot.getY() & 0xFF); + } + + file.close(); +} + +void PlottyFile::startPlotty(std::string filename) +{ + int code = system(("plotty --in " + filename).c_str()); + if(code) + throw std::runtime_error("Fehler beim Aufruf von plotty"); +} diff --git a/control/src/drv/plottyfile.h b/control/src/drv/plottyfile.h index 6197bf2..16a38d3 100644 --- a/control/src/drv/plottyfile.h +++ b/control/src/drv/plottyfile.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "dot.h" enum FunctionType