zeus
3 years ago
5 changed files with 250 additions and 510 deletions
@ -1,2 +1,3 @@ |
|||
* xref:index.adoc[Network Scanning] |
|||
* xref:index-analysis.adoc[Network analysis] |
|||
* xref:exer.adoc[Exercises] |
|||
|
@ -0,0 +1,249 @@ |
|||
= Network analysis! |
|||
|
|||
image::ROOT:swarmlab.png[swarmlab,150,float=right] |
|||
|
|||
|
|||
**tcpdump** is a common packet analyzer that runs under the command line. It allows the user to display TCP/IP and other packets being transmitted or received over a network to which the computer is attached. Distributed under the BSD license, tcpdump is free software. |
|||
|
|||
https://en.wikipedia.org/wiki/Tcpdump[More: wikipedia^] |
|||
|
|||
== Basic |
|||
|
|||
=== Everything on an interface |
|||
|
|||
Just see what’s going on, by looking at what’s hitting your interface. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump -i eth0 |
|||
---- |
|||
|
|||
=== Find Traffic by IP |
|||
|
|||
One of the most common queries, using host, you can see traffic that’s going to or from 1.1.1.1. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump host 1.1.1.1 |
|||
---- |
|||
|
|||
|
|||
=== Filtering by Source and/or Destination |
|||
|
|||
If you only want to see traffic in one direction or the other, you can use src and dst. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump src 1.1.1.1 |
|||
tcpdump dst 1.0.0.1 |
|||
---- |
|||
|
|||
=== Finding Packets by Network |
|||
|
|||
To find packets going to or from a particular network or subnet, use the net option. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump net 1.2.3.0/24 |
|||
---- |
|||
|
|||
|
|||
=== Show Traffic Related to a Specific Port |
|||
|
|||
You can find specific port traffic by using the port option followed by the port number. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump port 3389 |
|||
tcpdump src port 1025 |
|||
---- |
|||
|
|||
=== Show Traffic of One Protocol |
|||
|
|||
If you’re looking for one particular kind of traffic, you can use tcp, udp, icmp, and many others as well. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump icmp |
|||
---- |
|||
|
|||
=== Reading / Writing Captures to a File (pcap) |
|||
|
|||
It’s often useful to save packet captures into a file for analysis in the future. These files are known as PCAP (PEE-cap) files, and they can be processed by hundreds of different applications, including network analyzers, intrusion detection systems, and of course by tcpdump itself. Here we’re writing to a file called capture_file using the -w switch. |
|||
|
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump port 80 -w capture_file |
|||
---- |
|||
|
|||
|
|||
== Advanced |
|||
|
|||
|
|||
Now that we’ve seen what we can do with the basics through some examples, let’s look at some more advanced stuff. |
|||
|
|||
.More options |
|||
[source,bash] |
|||
---- |
|||
-X : Show the packet’s contents in both hex and ASCII. |
|||
-XX : Same as -X, but also shows the ethernet header. |
|||
-D : Show the list of available interfaces |
|||
-l : Line-readable output (for viewing as you save, or sending to other commands) |
|||
-q : Be less verbose (more quiet) with your output. |
|||
-t : Give human-readable timestamp output. |
|||
-tttt : Give maximally human-readable timestamp output. |
|||
-i eth0 : Listen on the eth0 interface. |
|||
-vv : Verbose output (more v’s gives more output). |
|||
-c : Only get x number of packets and then stop. |
|||
-s : Define the snaplength (size) of the capture in bytes. Use -s0 to get everything, unless you are intentionally capturing less. |
|||
-S : Print absolute sequence numbers. |
|||
-e : Get the ethernet header as well. |
|||
-q : Show less protocol information. |
|||
-E : Decrypt IPSEC traffic by providing an encryption key. |
|||
---- |
|||
|
|||
|
|||
[NOTE] |
|||
==== |
|||
It’s All About the Combinations |
|||
|
|||
Being able to do these various things individually is powerful, but the real magic of tcpdump comes from the ability to combine options in creative ways in order to isolate exactly what you’re looking for. There are three ways to do combinations, and if you’ve studied programming at all they’ll be pretty familiar to you. |
|||
|
|||
- AND |
|||
|
|||
and or && |
|||
|
|||
- OR |
|||
|
|||
or or || |
|||
|
|||
- EXCEPT |
|||
|
|||
not or ! |
|||
==== |
|||
|
|||
|
|||
=== From specific IP and destined for a specific Port |
|||
|
|||
Let’s find all traffic from 10.5.2.3 going to any host on port 3389. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump -nnvvS src 10.5.2.3 and dst port 3389 |
|||
---- |
|||
|
|||
|
|||
=== From One Network to Another |
|||
|
|||
Let’s look for all traffic coming from 192.168.x.x and going to the 10.x or 172.16.x.x networks, and we’re showing hex output with no hostname resolution and one level of extra verbosity. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16 |
|||
---- |
|||
|
|||
|
|||
=== Isolate TCP Flags |
|||
|
|||
You can also use filters to isolate packets with specific TCP flags set. |
|||
|
|||
==== Isolate TCP RST flags. |
|||
|
|||
The filters below find these various packets because tcp[13] looks at offset 13 in the TCP header, the number represents the location within the byte, and the !=0 means that the flag in question is set to 1, i.e. it’s on. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 4!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-rst' |
|||
---- |
|||
|
|||
==== Isolate TCP SYN flags. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 2!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-syn' |
|||
---- |
|||
|
|||
==== Isolate packets that have both the SYN and ACK flags set. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13]=18' |
|||
---- |
|||
|
|||
[NOTE] |
|||
==== |
|||
Only the PSH, RST, SYN, and FIN flags are displayed in tcpdump‘s flag field output. URGs and ACKs are displayed, but they are shown elsewhere in the output rather than in the flags field. |
|||
==== |
|||
|
|||
==== Isolate TCP URG flags. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 32!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-urg' |
|||
---- |
|||
|
|||
==== Isolate TCP ACK flags. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 16!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-ack' |
|||
---- |
|||
|
|||
==== Isolate TCP PSH flags. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 8!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-psh' |
|||
---- |
|||
|
|||
==== Isolate TCP FIN flags. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'tcp[13] & 1!=0' |
|||
tcpdump 'tcp[tcpflags] == tcp-fin' |
|||
---- |
|||
|
|||
|
|||
=== Find Traffic With Evil Bit |
|||
|
|||
There’s a bit in the IP header that never gets set by legitimate applications, which we call the “Evil Bit”. Here’s a fun filter to find packets where it’s been toggled. |
|||
|
|||
[source,bash] |
|||
---- |
|||
tcpdump 'ip[6] & 128 != 0' |
|||
---- |
|||
|
|||
=== Summary |
|||
|
|||
Here are the takeaways. |
|||
|
|||
[NOTE] |
|||
==== |
|||
- **tcpdump** is a valuable tool for anyone looking to get into networking or **information security**. |
|||
- The raw way it interfaces with traffic, combined with the precision it offers in inspecting packets make **it the best possible tool** for learning TCP/IP. |
|||
- Protocol Analyzers like **Wireshark** are great, but if you want to truly master **packet-fu**, you must become one with tcpdump |
|||
==== |
|||
|
|||
|
|||
[appendix] |
|||
== How to use tcpdump |
|||
|
|||
|
|||
This exercise will show you how to isolate traffic in various ways—from IP, to port, to protocol, to application-layer traffic—to make sure you find exactly what you need as quickly as possible. |
|||
|
|||
https://danielmiessler.com/study/tcpdump[Origin^] |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -1,505 +0,0 @@ |
|||
= Sensor node IMU |
|||
|
|||
|
|||
.The typical architecture of the sensor node |
|||
image::ROOT:sensorNode.jpg[alt="The typical architecture of the sensor node"] |
|||
|
|||
The main components of a sensor node are a **microcontroller**, **transceiver/Communication Module**, **memory**, **power source** and one or more **sensors.** |
|||
|
|||
== Sensor node example using IMU sensors |
|||
|
|||
A basic IMU (Intertial Measurement Unit) generally provides raw sensor data, whereas an AHRS takes this data one step further, converting it into heading or direction in degrees, converting the raw altitude data into standard units like feet or meters, etc. |
|||
|
|||
.AHRS (Attitude and Heading Reference System) |
|||
[NOTE] |
|||
==== |
|||
An attitude and heading reference system (AHRS) consists of sensors on three axes that provide attitude information for aircraft, including roll, pitch and yaw. These are sometimes referred to as MARG (Magnetic, Angular Rate, and Gravity) sensors and consist of either solid-state or microelectromechanical systems (MEMS) gyroscopes, accelerometers and magnetometers. They are designed to replace traditional mechanical gyroscopic flight instruments. |
|||
[More Info]https://en.wikipedia.org/wiki/Attitude_and_heading_reference_system[^] |
|||
==== |
|||
|
|||
=== IMU |
|||
|
|||
image::ROOT:sensors_1604_LRG.jpg[alt="Adafruit 10-DOF IMU Breakout"] |
|||
|
|||
Adafruit's 10DOF https://en.wikipedia.org/wiki/Degrees_of_freedom[(10 Degrees of Freedom)^] breakout board allows you to capture ten distinct types of motion or orientation related data. |
|||
|
|||
|
|||
- LSM303DLHC - a 3-axis accelerometer (up to +/-16g) and a 3-axis magnetometer (up to +/-8.1 gauss) on a single die |
|||
- L3GD20 - a 3-axis gyroscope (up to +/-2000 dps) |
|||
- BMP180 - A barometric pressure sensor (300..1100 hPa) that can be used to calculate altitude, with an additional on-board temperature sensor |
|||
|
|||
=== Connecting It Up |
|||
|
|||
Basic Setup |
|||
|
|||
- Connect the **SCL** pin on the breakout to the **SCL** pin on your Arduino. On an UNO & '328 based Arduino, this is also known as **A5** |
|||
- Connect the **SDA** pin on the breakout to the **SDA** pin on your Arduino. On an UNO & '328 based Arduino, this is also known as **A4** |
|||
- Connect the **VIN** pin on the breakout to **3.3V** or **5V** on your Uno (5V is preferred but if you have a 3V logic Arduino 3V is best) |
|||
- Connect the **GND** pin on the breakout to the **GND** pin on your Uno |
|||
|
|||
That's it! With those four wires, you should be able to talk to any of the I2C chips on the board and run any of the example sketches. |
|||
|
|||
|
|||
image::ROOT:sensors_10dofwire.jpg[alt="Connecting"] |
|||
|
|||
Advanced Setup |
|||
|
|||
- **GINT** - The interrupt pin on the L3GD20 gyroscope |
|||
- **GRDY** - The 'ready' pin on the L3GD20 gyroscope |
|||
- **LIN1** - Interrupt pin 1 on the LSM303DLHC |
|||
- **LIN2** - Interrupt pin 2 on the LSM303DLHC |
|||
- **LRDY** - The ready pin on the LSM303DLHC |
|||
|
|||
These pins are all outputs from the 10-DOF breakout and are all 3.3V logic |
|||
|
|||
|
|||
=== Downloading Libraries |
|||
|
|||
Place the files in the Arduino Sketch Folder '/libraries' sub-folder. You should end up with a structure like this: |
|||
|
|||
- arduinosketches/libraries/Adafruit_10DOF |
|||
- arduinosketches/libraries/Adafruit_BMP085 |
|||
- arduinosketches/libraries/Adafruit_L3GD20_U |
|||
- arduinosketches/libraries/Adafruit_LSM303DLHC |
|||
- arduinosketches/libraries/Adafruit_Sensor |
|||
|
|||
.Arduino libraries |
|||
[NOTE] |
|||
==== |
|||
Arduino libraries are a convenient way to share code such as device drivers or commonly used utility functions. |
|||
https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use[How to install Arduino libraries^] |
|||
==== |
|||
|
|||
=== Example Sketch |
|||
|
|||
==== pitch & roll |
|||
|
|||
|
|||
.sketch pitchrollheading |
|||
[source,c] |
|||
---- |
|||
sensors_event_t accel_event; |
|||
sensors_vec_t orientation; |
|||
|
|||
/* Calculate pitch and roll from the raw accelerometer data */ |
|||
accel.getEvent(&accel_event); |
|||
if (dof.accelGetOrientation(&accel_event, &orientation)) |
|||
{ |
|||
/* 'orientation' should have valid .roll and .pitch fields */ |
|||
Serial.print(F("Roll: ")); |
|||
Serial.print(orientation.roll); |
|||
Serial.print(F("; ")); |
|||
Serial.print(F("Pitch: ")); |
|||
Serial.print(orientation.pitch); |
|||
Serial.print(F("; ")); |
|||
} |
|||
---- |
|||
|
|||
|
|||
image::ROOT:800px-Flight_dynamics_with_text.png[alt="pitchroll"] |
|||
|
|||
Arguments |
|||
|
|||
- event: The **sensors_event_t** variable containing the data from the **accelerometer** |
|||
- orientation: The **sensors_vec_t** object that will have its **.pitch** and **.roll** fields populated |
|||
|
|||
Returns |
|||
|
|||
- **true** if the operation was successful, |
|||
- **false** if there was an error |
|||
|
|||
|
|||
image::ROOT:piandrroll.png[alt="pitchroll"] |
|||
|
|||
|
|||
|
|||
|
|||
== A real AHRS system |
|||
|
|||
|
|||
=== Loading the AHRS Sketch |
|||
|
|||
.AHRS Sketch |
|||
[source,c] |
|||
---- |
|||
#include <Wire.h> |
|||
#include <Adafruit_Sensor.h> |
|||
#include <Adafruit_LSM303_U.h> |
|||
#include <Adafruit_BMP085_U.h> |
|||
#include <Adafruit_Simple_AHRS.h> |
|||
|
|||
// Create sensor instances. |
|||
Adafruit_LSM303_Accel_Unified accel(30301); |
|||
Adafruit_LSM303_Mag_Unified mag(30302); |
|||
Adafruit_BMP085_Unified bmp(18001); |
|||
|
|||
// Create simple AHRS algorithm using the above sensors. |
|||
Adafruit_Simple_AHRS ahrs(&accel, &mag); |
|||
|
|||
// Update this with the correct SLP for accurate altitude measurements |
|||
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; |
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
Serial.println(F("Adafruit 10 DOF Board AHRS Example")); Serial.println(""); |
|||
|
|||
// Initialize the sensors. |
|||
accel.begin(); |
|||
mag.begin(); |
|||
bmp.begin(); |
|||
} |
|||
|
|||
void loop(void) |
|||
{ |
|||
sensors_vec_t orientation; |
|||
|
|||
// Use the simple AHRS function to get the current orientation. |
|||
if (ahrs.getOrientation(&orientation)) |
|||
{ |
|||
/* 'orientation' should have valid .roll and .pitch fields */ |
|||
Serial.print(F("Orientation: ")); |
|||
Serial.print(orientation.roll); |
|||
Serial.print(F(" ")); |
|||
Serial.print(orientation.pitch); |
|||
Serial.print(F(" ")); |
|||
Serial.print(orientation.heading); |
|||
Serial.println(F("")); |
|||
} |
|||
|
|||
// Calculate the altitude using the barometric pressure sensor |
|||
sensors_event_t bmp_event; |
|||
bmp.getEvent(&bmp_event); |
|||
if (bmp_event.pressure) |
|||
{ |
|||
/* Get ambient temperature in C */ |
|||
float temperature; |
|||
bmp.getTemperature(&temperature); |
|||
/* Convert atmospheric pressure, SLP and temp to altitude */ |
|||
Serial.print(F("Alt: ")); |
|||
Serial.print(bmp.pressureToAltitude(seaLevelPressure, |
|||
bmp_event.pressure, |
|||
temperature)); |
|||
Serial.println(F("")); |
|||
/* Display the temperature */ |
|||
Serial.print(F("Temp: ")); |
|||
Serial.print(temperature); |
|||
Serial.println(F("")); |
|||
} |
|||
|
|||
delay(500); |
|||
} |
|||
---- |
|||
|
|||
=== compile |
|||
|
|||
- Compile the sketch, |
|||
- open up the Serial Monitor (Tools > Serial Monitor), |
|||
- set the baud rate to 115200 |
|||
|
|||
|
|||
.output |
|||
image::ROOT:sensors_01_AHRSOutput.png[alt="AHRS raw data"] |
|||
|
|||
This raw data shows the main orientation data, consisting of 'roll', 'pitch' and 'heading' (or 'yaw) in degrees, followed by the current altitude and temperature |
|||
|
|||
|
|||
|
|||
=== Using AHRS Data |
|||
|
|||
The AHRS sketchs reads raw data from the board's accelerometer/magnetometer and converts the raw data into easy to understand **Euler angles.** |
|||
|
|||
In this case, we can see that the **roll is about 18°**, the **pitch is about 78°** and the **heading or yaw is about 32°**, and the sketch will keep updating itself with the latest values at whatever speed we've set in the sketch. |
|||
|
|||
[NOTE] |
|||
==== |
|||
.Euler angles, one of the possible ways to describe an orientation |
|||
image::ROOT:Eulerangles.svg.png[alt="Euler angles"] |
|||
|
|||
The first attempt to represent an orientation is attributed to Leonhard Euler. He imagined three reference frames that could rotate one around the other, and realized that by starting with a fixed reference frame and performing three rotations, he could get any other reference frame in the space (using two rotations to fix the vertical axis and other to fix the other two axes). The values of these three rotations are called Euler angles. |
|||
|
|||
.Tait–Bryan angles, another way to describe orientation |
|||
image::ROOT:Taitbrianzyx.svg.png[alt="Tait–Bryan angles"] |
|||
|
|||
These are three angles, also known as yaw, pitch and roll, Navigation angles and Cardan angles. Mathematically they constitute a set of six possibilities inside the twelve possible sets of Euler angles, the ordering being the one best used for describing the orientation of a vehicle such as an airplane. In aerospace engineering they are usually referred to as Euler angles. |
|||
|
|||
https://en.wikipedia.org/wiki/Rigid_body_dynamics[More Info: Rigid_body_dynamics^] |
|||
|
|||
https://en.wikipedia.org/wiki/Euler_angles[More Info: Eulers angles^] |
|||
|
|||
https://en.wikipedia.org/wiki/Leonhard_Euler[Leonhard Euler^] |
|||
==== |
|||
|
|||
|
|||
=== Save/Sending the Data |
|||
|
|||
This raw data can then be sent over the network to the central application. |
|||
|
|||
This will be the subject of another Lab Lesson |
|||
|
|||
=== Visualizing Data |
|||
|
|||
|
|||
|
|||
==== The tools, languages, and frameworks |
|||
|
|||
===== Three.js |
|||
|
|||
**Three.js** is a cross-browser JavaScript library and Application Programming Interface (API) used to create and display animated 3D computer graphics in a web browser. Three.js uses WebGL. |
|||
|
|||
|
|||
===== Processing |
|||
|
|||
**Processing** is an open-source graphical library and integrated development environment (IDE) built for the electronic arts, new media art, and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context. |
|||
|
|||
Processing uses the Java language, with additional simplifications such as additional classes and aliased mathematical functions and operations. It also provides a graphical user interface for simplifying the compilation and execution stage. |
|||
|
|||
The Processing language and IDE were the precursor to other projects including Arduino, Wiring and p5.js. |
|||
|
|||
===== p5.js |
|||
|
|||
In 2013, Lauren McCarthy created p5.js, a native JavaScript alternative to Processing.js that has the official support of the Processing Foundation. |
|||
|
|||
===== Processing.py |
|||
|
|||
Python Mode for Processing, or Processing.py is a Python interface to the underlying Java toolkit. It was chiefly developed by Jonathan Feinberg starting in 2010, with contributions from James Gilles and Ben Alkov |
|||
|
|||
|
|||
|
|||
[NOTE] |
|||
==== |
|||
**ThreeJS** is a wrapper around the browser’s native WebGL API. It’s the de facto standard 3D library — there are others, like BabylonJS, but Three is just miles more popular. The native browser APIs are… painful to work with, you can think of ThreeJS kinda like a jQuery for in-browser 3D graphics. Doesn’t give you anything that’s not already there, it just wraps it all into a user-friendly API |
|||
|
|||
**P5** is not a 3d graphics library, it’s an API for doing creative coding: things like procedural generation, natural simulations etc. It has some 3D features because it wraps the native WebGL API, but that’s not it’s core purpose. It is a artistic and teaching tool — it is occasionally used in production outside of artistic audio/visual stuff, but not often. It’s basically the JS version of Processing. |
|||
|
|||
==== |
|||
|
|||
https://www.slideshare.net/victorporof/processingjs-vs-threejs[More: Processing.js vs. three.js^] |
|||
|
|||
|
|||
==== Requirements |
|||
|
|||
To visualize the data, we've put together a basic **Processing** sketch that loads a 3D model and renders it using the data generated by the AHRS sketch. |
|||
|
|||
- https://processing.org/[Processing^] |
|||
- https://code.google.com/archive/p/saitoobjloader/#Download[OBJ Loader library for Processing^] |
|||
- http://www.lagers.org.uk/g4p/[G4P GUI library for Processing^] |
|||
|
|||
[NOTE] |
|||
==== |
|||
The OBJ library is required to load 3D models. It isn't strictly necessary and you could also render a boring cube in Processing, but why play with cubes when you have rabbits?! |
|||
==== |
|||
|
|||
|
|||
==== Write the Processing Sketch |
|||
|
|||
.Processing Sketch |
|||
[source,c] |
|||
---- |
|||
import processing.serial.*; |
|||
import java.awt.datatransfer.*; |
|||
import java.awt.Toolkit; |
|||
import processing.opengl.*; |
|||
import saito.objloader.*; |
|||
import g4p_controls.*; |
|||
|
|||
float roll = 0.0F; |
|||
float pitch = 0.0F; |
|||
float yaw = 0.0F; |
|||
float temp = 0.0F; |
|||
float alt = 0.0F; |
|||
|
|||
OBJModel model; |
|||
|
|||
// Serial port state. |
|||
Serial port; |
|||
String buffer = ""; |
|||
final String serialConfigFile = "serialconfig.txt"; |
|||
boolean printSerial = false; |
|||
|
|||
// UI controls. |
|||
GPanel configPanel; |
|||
GDropList serialList; |
|||
GLabel serialLabel; |
|||
GCheckbox printSerialCheckbox; |
|||
|
|||
void setup() |
|||
{ |
|||
size(400, 500, OPENGL); |
|||
frameRate(30); |
|||
model = new OBJModel(this); |
|||
model.load("bunny.obj"); |
|||
model.scale(20); |
|||
|
|||
// Serial port setup. |
|||
// Grab list of serial ports and choose one that was persisted earlier or default to the first port. |
|||
int selectedPort = 0; |
|||
String[] availablePorts = Serial.list(); |
|||
if (availablePorts == null) { |
|||
println("ERROR: No serial ports available!"); |
|||
exit(); |
|||
} |
|||
String[] serialConfig = loadStrings(serialConfigFile); |
|||
if (serialConfig != null && serialConfig.length > 0) { |
|||
String savedPort = serialConfig[0]; |
|||
// Check if saved port is in available ports. |
|||
for (int i = 0; i < availablePorts.length; ++i) { |
|||
if (availablePorts[i].equals(savedPort)) { |
|||
selectedPort = i; |
|||
} |
|||
} |
|||
} |
|||
// Build serial config UI. |
|||
configPanel = new GPanel(this, 10, 10, width-20, 90, "Configuration (click to hide/show)"); |
|||
serialLabel = new GLabel(this, 0, 20, 80, 25, "Serial port:"); |
|||
configPanel.addControl(serialLabel); |
|||
serialList = new GDropList(this, 90, 20, 200, 200, 6); |
|||
serialList.setItems(availablePorts, selectedPort); |
|||
configPanel.addControl(serialList); |
|||
printSerialCheckbox = new GCheckbox(this, 5, 50, 200, 20, "Print serial data"); |
|||
printSerialCheckbox.setSelected(printSerial); |
|||
configPanel.addControl(printSerialCheckbox); |
|||
// Set serial port. |
|||
setSerialPort(serialList.getSelectedText()); |
|||
} |
|||
|
|||
void draw() |
|||
{ |
|||
background(0,0, 0); |
|||
|
|||
// Set a new co-ordinate space |
|||
pushMatrix(); |
|||
|
|||
// Simple 3 point lighting for dramatic effect. |
|||
// Slightly red light in upper right, slightly blue light in upper left, and white light from behind. |
|||
pointLight(255, 200, 200, 400, 400, 500); |
|||
pointLight(200, 200, 255, -400, 400, 500); |
|||
pointLight(255, 255, 255, 0, 0, -500); |
|||
|
|||
// Displace objects from 0,0 |
|||
translate(200, 350, 0); |
|||
|
|||
// Rotate shapes around the X/Y/Z axis (values in radians, 0..Pi*2) |
|||
rotateX(radians(roll)); |
|||
rotateZ(radians(pitch)); |
|||
rotateY(radians(yaw)); |
|||
|
|||
pushMatrix(); |
|||
noStroke(); |
|||
model.draw(); |
|||
popMatrix(); |
|||
popMatrix(); |
|||
//print("draw"); |
|||
} |
|||
|
|||
void serialEvent(Serial p) |
|||
{ |
|||
String incoming = p.readString(); |
|||
if (printSerial) { |
|||
println(incoming); |
|||
} |
|||
|
|||
if ((incoming.length() > 8)) |
|||
{ |
|||
String[] list = split(incoming, " "); |
|||
if ( (list.length > 0) && (list[0].equals("Orientation:")) ) |
|||
{ |
|||
roll = float(list[1]); |
|||
pitch = float(list[2]); |
|||
yaw = float(list[3]); |
|||
buffer = incoming; |
|||
} |
|||
if ( (list.length > 0) && (list[0].equals("Alt:")) ) |
|||
{ |
|||
alt = float(list[1]); |
|||
buffer = incoming; |
|||
} |
|||
if ( (list.length > 0) && (list[0].equals("Temp:")) ) |
|||
{ |
|||
temp = float(list[1]); |
|||
buffer = incoming; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Set serial port to desired value. |
|||
void setSerialPort(String portName) { |
|||
// Close the port if it's currently open. |
|||
if (port != null) { |
|||
port.stop(); |
|||
} |
|||
try { |
|||
// Open port. |
|||
port = new Serial(this, portName, 115200); |
|||
port.bufferUntil('\n'); |
|||
// Persist port in configuration. |
|||
saveStrings(serialConfigFile, new String[] { portName }); |
|||
} |
|||
catch (RuntimeException ex) { |
|||
// Swallow error if port can't be opened, keep port closed. |
|||
port = null; |
|||
} |
|||
} |
|||
|
|||
// UI event handlers |
|||
|
|||
void handlePanelEvents(GPanel panel, GEvent event) { |
|||
// Panel events, do nothing. |
|||
} |
|||
|
|||
void handleDropListEvents(GDropList list, GEvent event) { |
|||
// Drop list events, check if new serial port is selected. |
|||
if (list == serialList) { |
|||
setSerialPort(serialList.getSelectedText()); |
|||
} |
|||
} |
|||
|
|||
void handleToggleControlEvents(GToggleControl checkbox, GEvent event) { |
|||
// Checkbox toggle events, check if print events is toggled. |
|||
if (checkbox == printSerialCheckbox) { |
|||
printSerial = printSerialCheckbox.isSelected(); |
|||
} |
|||
} |
|||
---- |
|||
|
|||
|
|||
|
|||
==== Run it |
|||
|
|||
- Run the AHRS Sketch on the Uno |
|||
- Run the Processing Sketch on the Processing |
|||
|
|||
|
|||
[NOTE] |
|||
==== |
|||
Make sure that the appropriate AHRS example sketch is running on the Uno (as described), and that the Serial Monitor is closed. |
|||
==== |
|||
|
|||
.And Voila! |
|||
video::CoyU3W925io[youtube] |
|||
image::ROOT:sensors_bunny.png[alt="Processing example"] |
|||
|
|||
|
|||
|
|||
|
|||
.Cockpit Simulator |
|||
[NOTE] |
|||
==== |
|||
With small changes we can make this too |
|||
|
|||
image::ROOT:sensors_Yaw_Axis_Corrected.png[Aeroplane,120,120,pdfwidth=25%,scaledwidth=25%] |
|||
|
|||
image::ROOT:HSI.png[alt="Cockpit"] |
|||
image::ROOT:TC.png[alt="Cockpit"] |
|||
==== |
|||
|
|||
|
|||
|
|||
|
|||
[appendix] |
|||
== Source Code |
|||
|
|||
- https://github.com/adafruit/Adafruit_AHRS[Adafruit_AHRS^] |
|||
- https://sourceforge.net/projects/g4p/files/?source=navbar[g4p^] |
|||
|
|||
|
@ -1,4 +0,0 @@ |
|||
antora --fetch /antora/site-intro.yml |
|||
antora /antora/site-intro.yml |
|||
ifconfig |
|||
http-server build/site -c-1 |
Loading…
Reference in new issue