Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ethernet support #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ This should print the python version and start the python REPL.
```> wine python -c 'import matplotlib; import serial; import typing; import pywintypes'```
The exit code should be 0.

## Repository Layout
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this.

* include/Telemetry - Contains Telemetry.h file detailing communication conventions for the Arduino. Must change paramater to switch communication modes between Serial, Ethernet TCP, Ethernet UDP, etc.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: paramater->parameter

* libs - Contains Telemetry.zip of Telemetry.h file for easy distribution to Arduino.
* build_tools - A link to another repository of the same name. Contains tools to distribute the GUI, to run it on multiple platforms.
* dist - Contains built executables of the GUI, one for both Windows/*nix systems. Includes various configurations, such as mk1/2_static_test, pressure_test, flight, demo_static_test, etc.
* drivers - Contains Python3 scripts specifying the design of each GUI to be built in dist/ directory. The demo, mk1, and mk2 scripts are wrappers around static_test_gui.py, the main script.
* src - Contains Python3 scripts handling the components of the GUI and the GUI class. Includes plotting, managing, and IO (serial, ethernet, etc) classes.

## TODO items
### Enhancements
* Proper support for shared x axis
Expand Down
108 changes: 86 additions & 22 deletions include/Telemetry/Telemetry.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Contains defs for standard packet io protocol
// To read floating point numbers, you need to change your arduino configuration settings

// The code & macros in this file are ONLY run on the Arduino end, the test-stand end

// This just works, OK?

#ifndef _TELEMETRY_H
Expand All @@ -9,6 +11,68 @@
#include "Arduino.h"
#include <avr/pgmspace.h>

// Set the protocall here: Serial, Ethernet
#define Protocall Ethernet_TCP
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error: protocall -> protocol

Also, this helper stuff generally looks pretty reasonable, although I would request that macros/defines are named as ALL_CAPS, just as a style thing.


#if Protocall == Serial
#define Pr(x) Serial.print(x)
#define Prln(x) Serial.println(x)
#define Read() Serial.read()
#define Avail() Serial.available()
#define Flush() Serial.flush()
#define INIT_GLOBALS() do{}while(0)
#define SETUP() Serial.begin(9600)

#elif Protocall == Ethernet_TCP
#include <Ethernet.h>
#define Pr(x) server.print(x)
#define Prln(x) server.println(x)
#define Read() client.read()
#define Avail() client.available()
#define Flush() client.flush()
#define INIT_GLOBALS do{ \
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; \
IPAddress ip(192, 168, 1, 177); \
// IPAddress myDns(192,168,1, 1); \
// IPAddress gateway(192, 168, 1, 1); \
// IPAddress subnet(255, 255, 0, 0); \
EthernetServer server(5005); \
EthernetClient client; \
} while(0)
#define SETUP do{ \
Ethernet.begin(mac, ip); \
server.begin(); \
while(!(client = server.available())); \
assert(client); \ // Not sure about this, discuss
} while(0)

#elif Protocall == Ethernet_UDP
#include <Ethernet.h>
#include <EthernetUdp.h>
#define Pr(x) do{ \
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); \
Udp.write(x); \
Udp.endPacket(); \
} while(0)
#define Prln(x) Pr(x.concat('\n'))
#define Read() Udp.read()
#define Avail() Udp.parsePacket()
#define Flush()
#define INIT_GLOBALS do{ \
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; \
IPAddress ip(192, 168, 1, 177); \
unsigned int port 5005; \
EthernetUDP Udp; \
} while(0)
#define SETUP do{ \
Ethernet.begin(mac, ip); \
Udp.begin(port); \
} while(0)

#else
assert(false);
#endif

// Defs for simulating C++ ostream
/* template<class T> */
/* inline Print &operator <<(Print &stream, T arg) */
Expand All @@ -20,28 +84,28 @@
/* { obj.println(); return obj; } */

#define BEGIN_SEND { \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the actual protocol, I've been considering making a significant change to this for Ethernet. The only reason for the weird thing with @@@@@ and &&&&& was a workaround for the issue that we only had one method of output, and I didn't want debugging Serial.print(...) statements to break telemetry.

Since Ethernet doesn't need to include this same sort of debugging flexibility, we could do away with the opening and closing symbols, slightly improving performance. We can change actual status/error messages, currently sent via Serial, to send as just another data field instead.

IDK, just a thought. But this is something we don't need to change right now, I can mess with it later.

Serial.print(F("@@@@@_time:")); \
Serial.print(millis());
Pr(F("@@@@@_time:")); \
Pr(millis());

#define SEND_ITEM(field, value) \
Serial.print(F(";")); \
Serial.print(F(#field)); \
Serial.print(F(":")); \
Serial.print(value);
Pr(F(";")); \
Pr(F(#field)); \
Pr(F(":")); \
Pr(value);

#define SEND_GROUP_ITEM(value) \
Serial.print(F(",")); \
Serial.print(value);
Pr(F(",")); \
Pr(value);

#define SEND_ITEM_NAME(field, value) \
Serial.print(F(";")); \
Serial.print(field); \
Serial.print(F(":")); \
Serial.print(value);
Pr(F(";")); \
Pr(field); \
Pr(F(":")); \
Pr(value);

#define END_SEND \
Serial.println(F("&&&&&")); \
Serial.flush(); \
Prln(F("&&&&&")); \
Flush; \
}

#define SEND(field, value) \
Expand All @@ -59,34 +123,34 @@ char _buffer[READ_BUFFER_SIZE];
char _data[READ_BUFFER_SIZE - 10];

#define CHECK_SERIAL_AVAIL \
if (!Serial.available()) { \
if (!Avail()) { \
delay(100); \
if (!Serial.available()) { \
Serial.println(F("READ timeout")); \
if (!Avail()) { \
Prln(F("READ timeout")); \
goto L_ENDREAD; \
} \
}

// Sorry about the gotos, only needed because macros.
#define BEGIN_READ \
if (Serial.available()) { \
if (Avail()) { \
char _c = '\0'; \
int _i; \
for (_i = 0; _c != '\n'; _i++) { \
if (_i == READ_BUFFER_SIZE) { \
Serial.println(F("READ buffer overflow")); \
while (Serial.available() && Serial.read() != '\n') \
Prln(F("READ buffer overflow")); \
while (Avail() && Read() != '\n') \
CHECK_SERIAL_AVAIL \
goto L_ENDREAD; \
} \
CHECK_SERIAL_AVAIL \
_c = Serial.read(); \
_c = Read(); \
_buffer[_i] = _c; \
if (_c == '\r') _i--; \
} \
_buffer[_i] = '\0'; \
if (!sscanf(_buffer, "@@@@@%[^&]&&&&&", _data)) { \
Serial.println(F("READ packet error")); \
Prln(F("READ packet error")); \
goto L_ENDREAD; \
} \
if (0);
Expand Down