After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,541 @@ |
|||
= Sensor node/mote |
|||
Apostolos rootApostolos@swarmlab.io |
|||
// Metadata: |
|||
:description: IoT Διαδίκτυο των Αντικειμένων |
|||
:keywords: iot, imu, AHRS |
|||
:data-uri: |
|||
:toc: right |
|||
:toc-title: Πίνακας περιεχομένων |
|||
:toclevels: 4 |
|||
:source-highlighter: highlight |
|||
:icons: font |
|||
:sectnums: |
|||
|
|||
|
|||
|
|||
{empty} + |
|||
|
|||
== Sensor node |
|||
|
|||
A **sensor node**, also known as a **mote**, is a node in a sensor network that is capable of performing some processing, gathering sensory information and communicating with other connected nodes in the network. |
|||
|
|||
[NOTE] |
|||
==== |
|||
A mote is a node but a node is not always a mote |
|||
==== |
|||
|
|||
.The typical architecture of the sensor node |
|||
image:./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:./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:./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:./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:./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:./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:./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:./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::Rabbit10DOF.mp4[] |
|||
image:./sensors_bunny.png[alt="Processing example"] |
|||
|
|||
|
|||
|
|||
|
|||
.Cockpit Simulator |
|||
[NOTE] |
|||
==== |
|||
With small changes we can make this too |
|||
|
|||
image:./sensors_Yaw_Axis_Corrected.png[Aeroplane,120,120,pdfwidth=25%,scaledwidth=25%] |
|||
|
|||
image:./HSI.png[alt="Cockpit"] |
|||
image:./TC.png[alt="Cockpit"] |
|||
==== |
|||
|
|||
|
|||
|
|||
|
|||
[appendix] |
|||
== Source Code |
|||
|
|||
- https://github.com/adafruit/Adafruit_AHRS |
|||
- https://sourceforge.net/projects/g4p/files/?source=navbar |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
:hardbreaks: |
|||
|
|||
{empty} + |
|||
{empty} + |
|||
{empty} |
|||
|
|||
:!hardbreaks: |
|||
|
|||
''' |
|||
|
@ -0,0 +1,388 @@ |
|||
= Sensor node/mote Connect2Server |
|||
Apostolos rootApostolos@swarmlab.io |
|||
// Metadata: |
|||
:description: IoT Διαδίκτυο των Αντικειμένων |
|||
:keywords: iot, imu, AHRS |
|||
:data-uri: |
|||
:toc: right |
|||
:toc-title: Πίνακας περιεχομένων |
|||
:toclevels: 4 |
|||
:source-highlighter: highlight |
|||
:icons: font |
|||
:sectnums: |
|||
|
|||
|
|||
|
|||
{empty} + |
|||
|
|||
== Create a mote with Raspberry Pi |
|||
|
|||
The Raspberry Pi is a low-cost credit-card sized single-board computer. The Raspberry Pi was created in the UK by the Raspberry Pi Foundation. The Raspberry Pi Foundation's goal is to "advance the education of adults and children, particularly in the field of computers, computer science and related subjects." |
|||
|
|||
https://simple.wikipedia.org/wiki/Raspberry_Pi[Wikipedia] |
|||
|
|||
|
|||
.Raspberry Pi 2 Model B |
|||
image:./Raspberry_Pi_2_Model_B_v1.1_top_new.jpg[alt="Raspberry Pi 2 Model B"] |
|||
|
|||
[NOTE] |
|||
.Remember |
|||
==== |
|||
A mote is a node but a node is not always a mote! |
|||
|
|||
image:./arduino-connect-pi.jpg[alt="Raspberry Pi and Arduino"] |
|||
|
|||
==== |
|||
|
|||
|
|||
=== Install Raspberry Pi |
|||
|
|||
==== Step 1: Download Raspbian |
|||
|
|||
https://www.raspberrypi.org/downloads/raspbian/[Download] the Raspbian disc image - Choose Raspbian Lite |
|||
|
|||
[NOTE] |
|||
.Why Raspbian Lite? |
|||
==== |
|||
Because it is a lightweight version of the Raspbian and it doesn’t have a graphical user interface installed. |
|||
|
|||
This means that it doesn’t have any unnecessary software installed that we don’t need for our projects, so this makes it the perfect solution for future automation projects. |
|||
==== |
|||
|
|||
==== Step 2: Unzip the file |
|||
|
|||
|
|||
- Windows users, you’ll want 7-Zip. |
|||
- Linux users will use the appropriately named Unzip. |
|||
|
|||
|
|||
==== Step 3: Write the disc image to your microSD card |
|||
|
|||
Next, pop your microSD card into your computer and write the disc image to it. You’ll need a specific program to do this: |
|||
|
|||
- Windows users, your answer is https://sourceforge.net/projects/win32diskimager/[Win32 Disk Imager]. |
|||
- Linux people, https://www.balena.io/etcher/[Etcher – which also works on Windows – is what the Raspberry Pi Foundation recommends.] |
|||
|
|||
The process of actually writing the image will be slightly different across these programs, but it’s pretty self-explanatory no matter what you’re using. |
|||
|
|||
- Each of these programs will have you select the destination (make sure you’ve picked your microSD card!) and the disc image (the unzipped Raspbian file). |
|||
- Choose, double-check, and then hit the button to write. |
|||
|
|||
|
|||
==== Step 4: Enabling SSH |
|||
|
|||
- Windows users |
|||
|
|||
.Create ssh file (no extension) |
|||
image:./ssh-file-to-sd-card.jpg[alt="Create ssh file"] |
|||
|
|||
- Linux Users |
|||
|
|||
.Create ssh file |
|||
[source,bash] |
|||
---- |
|||
sudo fdisk -l |
|||
# find dev and Boot partition |
|||
sudo mkdir /mnt/sdcardP1 |
|||
sudo mount /dev/device_partion_boot /mnt/sdcardP1 -rw |
|||
cd /mnt/sdcardP1 |
|||
sudo touch ssh |
|||
---- |
|||
|
|||
==== Step 5: Put the microSD card in your Pi and boot up |
|||
|
|||
Your default credentials are username **pi** and password **raspberry** |
|||
|
|||
|
|||
==== Step 6: Access via SSH |
|||
|
|||
|
|||
- The boot protocol for the ethernet interface is set to DHCP by default |
|||
|
|||
You can find the open SSH ports on your network using the nmap utility: |
|||
|
|||
|
|||
.find ports on Network |
|||
[source,bash] |
|||
---- |
|||
nmap -p 22 --open -sV 192.168.1.0/24 |
|||
---- |
|||
|
|||
You should find your pi listed in the output along with the IP assigned to the pi. |
|||
|
|||
|
|||
- You can change the boot protocol to static and define a static IP address for the pi by editing the ifcfg-eth0 file: |
|||
|
|||
.static IP address |
|||
[source,bash] |
|||
---- |
|||
sudo fdisk -l |
|||
# find dev and Boot partition |
|||
sudo mkdir /mnt/sdcardP1 |
|||
sudo mount /dev/device_partion_ext /mnt/sdcardP1 -rw |
|||
cd /mnt/sdcardP1 |
|||
vi /etc/sysconfig/network-scripts/ifcfg-eth0 |
|||
---- |
|||
|
|||
Then edit the file to suit your needs |
|||
|
|||
.static IP address |
|||
[source,bash] |
|||
---- |
|||
DEVICE=eth0 |
|||
BOOTPROTO=static |
|||
ONBOOT=yes |
|||
NETWORK=192.168.1.0 |
|||
NETMASK=255.255.255.0 |
|||
IPADDR=192.168.1.200 |
|||
GATEWAY=192.168.1.1 |
|||
---- |
|||
|
|||
|
|||
==== Step 7: Configure your Raspberry Pi. |
|||
|
|||
**raspi-config** is the Raspberry Pi configuration tool |
|||
|
|||
|
|||
.config Pi |
|||
[source,bash] |
|||
---- |
|||
sudo raspi-config |
|||
---- |
|||
|
|||
It has the following options available: |
|||
|
|||
.config options |
|||
[source,bash] |
|||
---- |
|||
|
|||
┌───────────────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├────────────────────┐ |
|||
│ │ |
|||
│ 1 Change User Password Change password for the current user │ |
|||
│ 2 Network Options Configure network settings │ |
|||
│ 3 Boot Options Configure options for start-up │ |
|||
│ 4 Localisation Options Set up language and regional settings to match your location │ |
|||
│ 5 Interfacing Options Configure connections to peripherals │ |
|||
│ 6 Overclock Configure overclocking for your Pi │ |
|||
│ 7 Advanced Options Configure advanced settings │ |
|||
│ 8 Update Update this tool to the latest version │ |
|||
│ 9 About raspi-config Information about this configuration tool │ |
|||
│ │ |
|||
│ │ |
|||
│ │ |
|||
│ <Select> <Finish> │ |
|||
│ │ |
|||
└──────────────────────────────────────────────────────────────────────────────────────────────────┘ |
|||
|
|||
---- |
|||
|
|||
|
|||
=== Arduino Uno Raspberry Pi Serial Communication |
|||
|
|||
==== Serial config on Raspi |
|||
|
|||
|
|||
.config 1 (recommended) |
|||
[source,bash] |
|||
---- |
|||
whoami |
|||
sudo usermod -a -G dialout pi |
|||
reboot |
|||
---- |
|||
|
|||
This gives read/write permission for all users to the Raspberry Pi (potentially unsafe): |
|||
|
|||
.config 2 |
|||
[source,bash] |
|||
---- |
|||
sudo chmod 777 /dev/ttyACM0 |
|||
---- |
|||
|
|||
This provides some configuration for the Arduino serial connection: |
|||
|
|||
.configuration for the Arduino serial connection |
|||
[source,bash] |
|||
---- |
|||
sudo stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts |
|||
---- |
|||
|
|||
==== Reading in arduino |
|||
|
|||
.C code in the arduino |
|||
[source,bash] |
|||
---- |
|||
void loop() { |
|||
meas = analogRead(a); |
|||
if (Serial.available()) |
|||
{ |
|||
if (Serial.read() == '1') |
|||
{ |
|||
Serial.println(meas); |
|||
} |
|||
} |
|||
} |
|||
---- |
|||
|
|||
==== Python |
|||
|
|||
.Python code in Raspberry Pi |
|||
[source,python] |
|||
---- |
|||
import serial |
|||
from datetime import datetime |
|||
from time import sleep |
|||
now = datetime.now() |
|||
|
|||
ser = serial.Serial('/dev/ttyACM0', 9600) |
|||
ser.write("1".encode()) |
|||
sleep(0.05); |
|||
s = ser.readline() |
|||
|
|||
file = open("dataset", "a") |
|||
file.write(now.strftime("%Y-%m-%d %H:%M") + " Sensor Value:" + str(s)+ "\n") |
|||
file.close() |
|||
---- |
|||
|
|||
==== PHP |
|||
|
|||
[NOTE] |
|||
.PHP Class |
|||
==== |
|||
https://gist.github.com/gravataLonga/6c89821b845d15e939a0/archive/0d0063684d388a8ff53df8e73e55f4cb1187d7cd.zip[Download Class] |
|||
==== |
|||
|
|||
.PHP code in Raspberry Pi - read |
|||
[source,php] |
|||
---- |
|||
<?php |
|||
|
|||
include "php_serial.class.php"; |
|||
|
|||
$serial = new phpSerial(); |
|||
$serial->deviceSet("/dev/ttyACM0"); |
|||
$serial->confBaudRate(9600); |
|||
$serial->confParity("none"); |
|||
$serial->confCharacterLength(8); |
|||
$serial->confStopBits(1); |
|||
$serial->confFlowControl("none"); |
|||
|
|||
$serial->deviceOpen(); |
|||
$read = $serial->readPort(); |
|||
$serial->deviceClose(); |
|||
|
|||
echo $read |
|||
---- |
|||
|
|||
|
|||
Sends a string to the Arduino. |
|||
|
|||
.PHP code in Raspberry Pi - send |
|||
[source,php] |
|||
---- |
|||
<?php |
|||
|
|||
error_reporting(E_ALL); |
|||
ini_set('display_errors', '1'); |
|||
include "php_serial.class.php"; |
|||
|
|||
$serial = new phpSerial; |
|||
$serial->deviceSet("/dev/ttyAMA0"); |
|||
$serial->confBaudRate(115200); |
|||
$serial->confParity("none"); |
|||
$serial->confCharacterLength(8); |
|||
$serial->confStopBits(1); |
|||
$serial->deviceOpen(); |
|||
$serial->sendMessage("Hello from my PHP script, say hi back!"); |
|||
|
|||
$serial->deviceClose(); |
|||
|
|||
echo "I've sended a message! \n\r"; |
|||
---- |
|||
|
|||
==== NodeJS |
|||
|
|||
[NOTE] |
|||
==== |
|||
Read the writing carefully on your Raspberry Pi circuit board to confirm it indicates something like “Raspberry Pi 4 Model B” or “Raspberry Pi 2 Model B”. If in doubt, run the following command in the terminal: |
|||
|
|||
$ uname -m |
|||
|
|||
If the result returned starts with **“armv6”**, you are running a Raspberry Pi based on the older ARMv6 chipset and the next Node.js installation step **will not work**; otherwise, you are ready for the next step. |
|||
==== |
|||
|
|||
|
|||
.Install NodeJS |
|||
[source,bash] |
|||
---- |
|||
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash - |
|||
sudo apt install -y nodejs |
|||
npm install raspi-serial |
|||
---- |
|||
|
|||
|
|||
.Install NodeJS - armv6 |
|||
[source,bash] |
|||
---- |
|||
cd ~ |
|||
wget http://nodejs.org/dist/v6.2.1/node-v6.2.1-linux-armv6l.tar.gz |
|||
tar -xzf node-v6.2.1-linux-armv6l.tar.gz |
|||
cd node-v6.2.1-linux-armv6l/ |
|||
sudo cp -R * /usr/local/ |
|||
export PATH=$PATH:/usr/local/bin |
|||
npm install raspi-serial |
|||
---- |
|||
|
|||
|
|||
.NodeJS code in Raspberry Pi - read |
|||
[source,c] |
|||
---- |
|||
mport { init } from 'raspi'; |
|||
import { Serial } from 'raspi-serial'; |
|||
|
|||
init(() => { |
|||
var serial = new Serial(); |
|||
serial.open(() => { |
|||
serial.on('data', (data) => { |
|||
process.stdout.write(data); |
|||
}); |
|||
serial.write('Hello from raspi-serial'); |
|||
}); |
|||
}); |
|||
---- |
|||
|
|||
|
|||
|
|||
=== Send data2server |
|||
|
|||
|
|||
==== NodeJS |
|||
|
|||
.NodeJS code in Raspberry Pi - send |
|||
[source,c] |
|||
---- |
|||
|
|||
... |
|||
var serverIOT=IP_SERVER |
|||
const socket = require('socket.io-client')('https://'+serverIOT+':9080'); |
|||
socket.on('connect', function () { |
|||
socket.emit('subscribe', log); |
|||
var obj = new Object(); |
|||
obj.room = log; |
|||
obj.message = data; |
|||
var text = JSON.stringify(obj); |
|||
var text1 = Buffer.from(text); |
|||
var text5 = text1.toString('base64'); |
|||
socket.emit('log', text5, log ) |
|||
//console.log(util.inspect(text5, false, null, true /* enable colors */)) |
|||
|
|||
res.json({ |
|||
'message':"ok" |
|||
}); |
|||
}); |
|||
|
|||
... |
|||
|
|||
---- |
|||
|
|||
TIP: You can find more information https://git.swarmlab.io:3000/zeus/iot-swarm-example/src/branch/master[here^] and http://docs.swarmlab.io/SwarmLab-HowTos/index-lab.adoc.html#_iot_swarm_implementation[here^] |
|||
|
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 707 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 34 KiB |
@ -0,0 +1,382 @@ |
|||
= Vim basic ! |
|||
Apostolos rootApostolos@swarmlab.io |
|||
// Metadata: |
|||
:description: Intro and Install |
|||
:keywords: ubuntu install dual |
|||
:data-uri: |
|||
:toc: right |
|||
:toc-title: Πίνακας περιεχομένων |
|||
:toclevels: 4 |
|||
:source-highlighter: highlight |
|||
:icons: font |
|||
:sectnums: |
|||
|
|||
|
|||
|
|||
{empty} + |
|||
|
|||
|
|||
|
|||
.vim |
|||
**** |
|||
Vim is the editor of choice for many developers and power users. |
|||
|
|||
It’s a _modal_ text editor based on the vi editor. |
|||
|
|||
It inherits the key bindings of vi, but also adds a great deal of functionality and extensibility that are missing from the original vi. |
|||
|
|||
[NOTE] |
|||
==== |
|||
*vim modals*: |
|||
|
|||
*insert* mode and *command* mode. |
|||
|
|||
TIP: vim *starts* in *command mode*. |
|||
|
|||
* command mode |
|||
** In this mode, characters you type is interpreted as a command |
|||
|
|||
* insert mode |
|||
** in insert mode, the characters you type is just inserted. |
|||
|
|||
TIP: To *enter insert* mode, press *i*. To get back in command mode, press *esc* |
|||
|
|||
==== |
|||
**** |
|||
|
|||
[NOTE] |
|||
==== |
|||
*All editors have a command and an input mode.* |
|||
|
|||
Most editors default to the input mode whithin which the text we type is interpretted as a raw string to be appendeed to the cursors position. |
|||
|
|||
To "enter" command mode we the have to use some king of control key/button. Thus the command mode is disguised and we only use it briefly. |
|||
|
|||
Vim on the other hand has *three distinct* modes: |
|||
|
|||
- normal mode: The COMMAND mode. Here we can insert commands that can perform all sorts of tasks just like the buttons we mentioned before. The difference is that vim will stay in normal mode unsless we tell it to enter another mode. This alowes for faster commands (no need for menus and mouse clicks) but also for more complicated commands (combos). |
|||
|
|||
- insert mode: the mode to INSERT text like in any other editor |
|||
|
|||
- visual mode: this mode exists in all editors, although it usually is combined into insert mode. Here we can do visual tasks like selecting text or highlighting regions. |
|||
==== |
|||
|
|||
== A simple workflow example with the vim editor. |
|||
Lets suppose we want to create a simple program that will print out "Hello world". |
|||
Like any good programmer we want our headder declarations seperatelly from our functions. |
|||
|
|||
So lets create our starting file "myprint.h" using the "$vim <path to file>" command, in our case "$vim ./myprint."h. |
|||
|
|||
That should have created the file and opened it inside the vim editor. |
|||
|
|||
We now are in command mode, but since we want to create some code we want to enter edit mode. |
|||
We can do that by pressing the 'i' key. |
|||
|
|||
Now lets add some text. Folowing our example we have: |
|||
[source,c++] |
|||
---- |
|||
#include <string> |
|||
#include <stdio.h> |
|||
|
|||
class MyPrint |
|||
{ |
|||
public: |
|||
std::string message="Hello World"; |
|||
int PrintMessage(); |
|||
}; |
|||
---- |
|||
|
|||
Ok our headder is now ready. Now we have to implement the "PrintMessage" function. |
|||
|
|||
Hence, lets create the source file. To do that we could exit vim and simply repeat the above steps but that would be really impracticall. |
|||
And vim is all about practicallity so there ought to be a simpler way!? |
|||
|
|||
Of course there is! We can simply open a new tab from whithin the existing editor!!! |
|||
|
|||
To do that simply type the command "tabnew <path to file>" in command mode, in our case "tabnew ./myprint.cc". |
|||
|
|||
TIP: Remember commands, unlike hotkeys, need a colon (:) at the beggining. So litterally speaking our command would be ":tabnew ./myprint.cc" |
|||
|
|||
Oops! I think I forgot how I named my function! |
|||
I will have to switch to the other tab again to look at the header. |
|||
|
|||
To do that i can simply hit "gt" in command mode. |
|||
This hotkey rotates through the tabs clockwise. |
|||
|
|||
If I wanted to rotate anticlockwize i could use "Gt" but since i only have two that would be kinda stupid. |
|||
|
|||
[NOTE] |
|||
==== |
|||
Like in this one, in most cases hitting shift along with the command does the exact opposite.(gt moves right,Gt moves left) |
|||
For example 'o' inserts an empty line underneath the one we are on.'O' will do the the opposite, it will insert a blank line above. |
|||
|
|||
TIP: the 'o'/'O' command will also initiate insert mode so we are ready to rock in our new line! |
|||
==== |
|||
|
|||
But now lets get back to our program. |
|||
|
|||
I now finally remember the name of the function so I will go ahead and write my implementation as follows: |
|||
[source,c++] |
|||
---- |
|||
#include <myprint.h> |
|||
|
|||
MyPrint::MyPrint() |
|||
{ |
|||
} |
|||
|
|||
int MyPrint::PrintMessage(void) |
|||
{ |
|||
printf("%s",this->message.c_str()); |
|||
return 0; |
|||
} |
|||
---- |
|||
|
|||
But I now realized I forgot to declare my constructor in my header file. |
|||
|
|||
Well instead of writing the same thing again we can simply copy it right? |
|||
|
|||
To copy move to the desired line and hit "yy" in command mode. NO that is not a typo, hit "y" two times! |
|||
|
|||
Now move to the desired line inside the header file and press "p". This will insert the line just below the cursor. |
|||
|
|||
After pasting our header should look something like this: |
|||
[source,c++] |
|||
---- |
|||
#include <string> |
|||
#include <stdio.h> |
|||
|
|||
class MyPrint |
|||
{ |
|||
public: |
|||
std::string message="Hello World"; |
|||
MyPrint::MyPrint() |
|||
int PrintMessage(); |
|||
}; |
|||
---- |
|||
|
|||
YES! This this code was obviously copied and pasted from above using the same hotkey you used right now!!! |
|||
|
|||
Now we can simply delete the parts we dont need and our coding is done for today! |
|||
|
|||
[source,c++] |
|||
---- |
|||
#include <string> |
|||
#include <stdio.h> |
|||
|
|||
class MyPrint |
|||
{ |
|||
public: |
|||
std::string message="Hello World"; |
|||
MyPrint() |
|||
int PrintMessage(); |
|||
}; |
|||
---- |
|||
Lets simply use the "w" command for writing the file and the "q" command for quitting the app. |
|||
(To write/quit multiple tabs just append "all" for example ":wall" or ":qall") |
|||
|
|||
TIP: If you would like to execute a system command (like mv or more likely git) you can do that from whithin vim by adding a "!" at the beggining. |
|||
|
|||
For example: |
|||
":!git commit -m"my program is ready!;"" |
|||
|
|||
== The vimrc |
|||
|
|||
=== settings |
|||
|
|||
*Vim, like all editors has different configuration options for the user to use (or not to use!);* |
|||
|
|||
These are written and saved whithin the "vimrc". |
|||
|
|||
Typically this file resides inside the home directory of a user like so "~/.vimrc". |
|||
|
|||
Here we can add all sorts of settings like colorschemes or line numbers, or even more breaking changes like changes to visual or normal mode. |
|||
|
|||
=== plugins |
|||
|
|||
The real power of vim shows when we add some basic plugins, like a linter, an autocomplete engine and a good colorscheme! |
|||
|
|||
All of that can be done using a simple tool called pluggin manager! |
|||
|
|||
There are many filemanagers out there. One of the most poppular and the one we use is "Plugged". |
|||
|
|||
For a fully loaded vimrc and an activelly maintained and updated repo please visit https://gitlab.com/dianshane/vim[https://gitlab.com/dianshane/vim^] |
|||
|
|||
You can also reffer there for any questions if you would like something explained. |
|||
|
|||
To download plug and find out how to install plugins you can follow the instructions found https://github.com/junegunn/vim-plug[here^]. |
|||
|
|||
== Vim Key Bindings |
|||
|
|||
=== Move |
|||
|
|||
.Key combinations |
|||
[options="header,footer"] |
|||
|======================= |
|||
|Key|Action | Followed by |
|||
|b |back word | |
|||
|e |end of word | |
|||
|f |find character after cursor in current line | |
|||
|m |mark current line and position mark character | tag (a-z) |
|||
|n |repeat last search | |
|||
|t |same as "f" but cursor moves to just before found character | character to find |
|||
|w |move foreward one word | |
|||
|z |position current line | CR = top; "." = center; "-"=bottom |
|||
|B |move back one Word | |
|||
|E |move to end of Word | |
|||
|F |backwards version of 'f' | character to find |
|||
|G |goto line number prefixed, or goto end if none | |
|||
|H |home cursor - goto first line on screen | |
|||
|J |join current line with next line | |
|||
|L |goto last line on screen | |
|||
|M |goto middle line on screen | |
|||
|N |repeat last search, but in opposite direction of original search | |
|||
|T |backwards version of "t" character to find | |
|||
|W |foreward Word | |
|||
|0 |move to column zero | |
|||
|! |shell command filter cursor motion command, shell command | |
|||
|$ |move to end of line | |
|||
|% |match nearest [],(),{} on line, to its match (same line or others) | |
|||
|^ |move to first non-whitespace character of line | |
|||
|( |move to previous sentence | |
|||
|) |move to next sentence | |
|||
|\| |move to column zero | |
|||
|- |move to first non-whitespace of previous line | |
|||
|+ |move to first non-whitespace of next line | |
|||
|[ |move to previous "{...}" section | "[" |
|||
|] |move to next "{...}" section | "]" |
|||
|{ |move to previous blank-line separated section | "{" |
|||
|} |move to next blank-line separated section | "}" |
|||
|' |move to marked line, first non-whitespace | character tag (a-z) |
|||
|` |move to marked line, memorized column | character tag (a-z) |
|||
|/ |search forward | search string, ESC or CR |
|||
|? |search backward | search string, ESC or CR |
|||
|^D |down half screen | |
|||
|^J |line down | |
|||
|^T |go to the file/code you were editing before the last tag jump | |
|||
|^U |up half screen | |
|||
|^^ |switch file buffers |
|||
|======================= |
|||
|
|||
|
|||
|
|||
|
|||
[source,bash] |
|||
---- |
|||
w // <1> |
|||
e // <2> |
|||
---- |
|||
<1> move the cursor forwards to the start of the next word |
|||
<2> move the cursor forwards to the end of the next word |
|||
|
|||
=== List |
|||
|
|||
|
|||
Allmost complete key binding reference |
|||
|
|||
.Definitions |
|||
[NOTE] |
|||
==== |
|||
- *word* - a lower-case word ("w", "b", "e" commands) is defined by a consecutive string of letters, numbers, or underscore, or a consecutive string of characters that is not any of {letters, numbers, underscore, whitespace} |
|||
- Word - an upper-case word ("W", "B", "E" commands) is a consecutive sequence of non-whitespace. |
|||
- *cursor motion command* - any command which positions the cursor is ok here, including the use of numeric prefixes. In addition, a repeat of the edit command usually means to apply to the entire current line. For example, "<<" means shift current line left; "cc" means replace entire current line; and "dd" means delete entire current line. |
|||
|
|||
*Key Bindings in Editing Modes* |
|||
- While in any edit mode (insert, replace, etc.) there are some keys that are used to adjust behaviour, rather than just to insert text. |
|||
|
|||
[source,bash] |
|||
---- |
|||
ESC - leave edit mode, return to command mode |
|||
^D - move line backwards one shiftwidth. shiftwidth must be set, and either the line must be newly added, or ^T must have been used. |
|||
^T - move all after cursor forwards one shiftwidth |
|||
---- |
|||
==== |
|||
|
|||
.Key combinations |
|||
[options="header,footer"] |
|||
|======================= |
|||
|Key|Action | Followed by |
|||
|a |enter insertion mode after current character | text, ESC |
|||
|b |back word | |
|||
|c |change command cursor | motion command |
|||
|d |delete command cursor | motion command |
|||
|e |end of word | |
|||
|f |find character after cursor in current line | |
|||
|i |enter insertion mode before current character | text, ESC |
|||
|m |mark current line and position mark character | tag (a-z) |
|||
|n |repeat last search | |
|||
|o |open line below and enter insertion mode | text, ESC |
|||
|p |put buffer after cursor |
|||
|r |replace single character at cursor | replacement character expected |
|||
|s |substitute single character with new text | text, ESC |
|||
|t |same as "f" but cursor moves to just before found character | character to find |
|||
|u |undo | |
|||
|w |move foreward one word | |
|||
|y |yank command | cursor motion command |
|||
|z |position current line | CR = top; "." = center; "-"=bottom |
|||
|A |enter insertion mode after end of line | text, ESC |
|||
|B |move back one Word | |
|||
|C |change to end of line | text, ESC |
|||
|D |delete to end of line | |
|||
|E |move to end of Word | |
|||
|F |backwards version of "f" | character to find |
|||
|G |goto line number prefixed, or goto end if none | |
|||
|H |home cursor - goto first line on screen | |
|||
|I |enter insertion mode before first non-whitespace character | text, ESC |
|||
|J |join current line with next line | |
|||
|L |goto last line on screen | |
|||
|M |goto middle line on screen | |
|||
|N |repeat last search, but in opposite direction of original search | |
|||
|O |open line above and enter insertion mode | text, ESC |
|||
|P |put buffer before cursor | |
|||
|Q |leave visual mode (go into "ex" mode) | |
|||
|R |replace mode - replaces through end of current line, then inserts | text, ESC |
|||
|S |substitute entire line - deletes line, enters insertion mode | text, ESC |
|||
|T |backwards version of "t" character to find | |
|||
|U |restores line to state when cursor was moved into it | |
|||
|W |foreward Word | |
|||
|Y |yank entire line | |
|||
|0 |move to column zero | |
|||
|1-9| numeric precursor to other commands [additional numbers (0-9)] command | |
|||
|! |shell command filter cursor motion command, shell command | | |
|||
|@ |vi eval buffer name (a-z) | |
|||
|$ |move to end of line | |
|||
|% |match nearest [],(),{} on line, to its match (same line or others) | |
|||
|^ |move to first non-whitespace character of line | |
|||
|& |repeat last ex substitution (":s ...") not including modifiers | |
|||
|( |move to previous sentence | |
|||
|) |move to next sentence | |
|||
|\| |move to column zero | |
|||
|- |move to first non-whitespace of previous line | |
|||
|_ |similar to '^' but uses numeric prefix oddly | |
|||
|+ |move to first non-whitespace of next line | |
|||
|[ |move to previous "{...}" section | "[" |
|||
|] |move to next "{...}" section | "]" |
|||
|{ |move to previous blank-line separated section | "{" |
|||
|} |move to next blank-line separated section | "}" |
|||
|; |repeat last "f", "F", "t", or "T" command | |
|||
|' |move to marked line, first non-whitespace | character tag (a-z) |
|||
|` |move to marked line, memorized column | character tag (a-z) |
|||
|: |ex-submode ex command | |
|||
|" |access numbered buffer; load or access lettered buffer | 1-9,a-z |
|||
|~ |reverse case of current character and move cursor forward | |
|||
|, |reverse direction of last "f", "F", "t", or "T" command | |
|||
|. |repeat last text-changing command | |
|||
|/ |search forward | search string, ESC or CR |
|||
|< |unindent command | cursor motion command |
|||
|> |indent command | cursor motion command |
|||
|? |search backward | search string, ESC or CR |
|||
|^D |down half screen | |
|||
|^G |show status | |
|||
|^J |line down | |
|||
|^T |go to the file/code you were editing before the last tag jump | |
|||
|^U |up half screen | |
|||
|^Z |suspend program | |
|||
|^[ |(ESC) cancel started command; otherwise UNBOUND | |
|||
|^\ |leave visual mode (go into "ex" mode) | |
|||
|^^ |switch file buffers |
|||
|======================= |
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,238 @@ |
|||
= Vim basic ! |
|||
Apostolos rootApostolos@swarmlab.io |
|||
// Metadata: |
|||
:description: Intro and Install |
|||
:keywords: ubuntu install dual |
|||
:data-uri: |
|||
:toc: right |
|||
:toc-title: Πίνακας περιεχομένων |
|||
:toclevels: 4 |
|||
:source-highlighter: highlight |
|||
:icons: font |
|||
:sectnums: |
|||
|
|||
|
|||
|
|||
{empty} + |
|||
|
|||
|
|||
|
|||
.vim |
|||
**** |
|||
Vim is the editor of choice for many developers and power users. |
|||
|
|||
It’s a _modal_ text editor based on the vi editor. |
|||
|
|||
It inherits the key bindings of vi, but also adds a great deal of functionality and extensibility that are missing from the original vi. |
|||
|
|||
[NOTE] |
|||
==== |
|||
*vim modals*: |
|||
|
|||
*insert* mode and *command* mode. |
|||
|
|||
TIP: vim *starts* in *command mode*. |
|||
|
|||
* command mode |
|||
** In this mode, characters you type is interpreted as a command |
|||
|
|||
* insert mode |
|||
** in insert mode, the characters you type is just inserted. |
|||
|
|||
TIP: To *enter insert* mode, press *i*. To get back in command mode, press *esc* |
|||
|
|||
==== |
|||
**** |
|||
|
|||
[NOTE] |
|||
==== |
|||
*All editors have a command and an input mode;* |
|||
|
|||
Most editors default to the input mode whithin which the text we type is interpretted as a raw string to be appendeed to the cursors position. |
|||
|
|||
To "enter" command mode we the have to use some king of control key/button. Thus the command mode is disguised and we only use it briefly. |
|||
|
|||
Vim on the other hand has three distinct modes: |
|||
|
|||
- normal mode: The COMMAND mode. Here we can insert commands that can perform all sorts of tasks just like the buttons we mentioned before. The difference is that vim will stay in normal mode unsless we tell it to enter another mode. This alowes for faster commands(no need for menus and mouse clicks) but also for more complicated commands (combos). |
|||
|
|||
- insert mode: the mode to INSERT text like in any other editor |
|||
|
|||
- visual mode: this mode exists in all editors, although it usually is combined into insert mode. Here we can do visual tasks like selecting text or highlighting regions. |
|||
==== |
|||
|
|||
== Vim Key Bindings |
|||
|
|||
=== Move |
|||
|
|||
.Key combinations |
|||
[options="header,footer"] |
|||
|======================= |
|||
|Key|Action | Followed by |
|||
|b |back word | |
|||
|e |end of word | |
|||
|f |find character after cursor in current line | |
|||
|m |mark current line and position mark character | tag (a-z) |
|||
|n |repeat last search | |
|||
|t |same as "f" but cursor moves to just before found character | character to find |
|||
|w |move foreward one word | |
|||
|z |position current line | CR = top; "." = center; "-"=bottom |
|||
|B |move back one Word | |
|||
|E |move to end of Word | |
|||
|F |backwards version of 'f' | character to find |
|||
|G |goto line number prefixed, or goto end if none | |
|||
|H |home cursor - goto first line on screen | |
|||
|J |join current line with next line | |
|||
|L |goto last line on screen | |
|||
|M |goto middle line on screen | |
|||
|N |repeat last search, but in opposite direction of original search | |
|||
|T |backwards version of "t" character to find | |
|||
|W |foreward Word | |
|||
|0 |move to column zero | |
|||
|! |shell command filter cursor motion command, shell command | |
|||
|$ |move to end of line | |
|||
|% |match nearest [],(),{} on line, to its match (same line or others) | |
|||
|^ |move to first non-whitespace character of line | |
|||
|( |move to previous sentence | |
|||
|) |move to next sentence | |
|||
|\| |move to column zero | |
|||
|- |move to first non-whitespace of previous line | |
|||
|+ |move to first non-whitespace of next line | |
|||
|[ |move to previous "{...}" section | "[" |
|||
|] |move to next "{...}" section | "]" |
|||
|{ |move to previous blank-line separated section | "{" |
|||
|} |move to next blank-line separated section | "}" |
|||
|' |move to marked line, first non-whitespace | character tag (a-z) |
|||
|` |move to marked line, memorized column | character tag (a-z) |
|||
|/ |search forward | search string, ESC or CR |
|||
|? |search backward | search string, ESC or CR |
|||
|^D |down half screen | |
|||
|^J |line down | |
|||
|^T |go to the file/code you were editing before the last tag jump | |
|||
|^U |up half screen | |
|||
|^^ |switch file buffers |
|||
|======================= |
|||
|
|||
|
|||
|
|||
|
|||
[source,bash] |
|||
---- |
|||
w // <1> |
|||
e // <2> |
|||
---- |
|||
<1> move the cursor forwards to the start of the next word |
|||
<2> move the cursor forwards to the end of the next word |
|||
|
|||
=== List |
|||
|
|||
|
|||
Allmost complete key binding reference |
|||
|
|||
.Definitions |
|||
[NOTE] |
|||
==== |
|||
- *word* - a lower-case word ("w", "b", "e" commands) is defined by a consecutive string of letters, numbers, or underscore, or a consecutive string of characters that is not any of {letters, numbers, underscore, whitespace} |
|||
- Word - an upper-case word ("W", "B", "E" commands) is a consecutive sequence of non-whitespace. |
|||
- *cursor motion command* - any command which positions the cursor is ok here, including the use of numeric prefixes. In addition, a repeat of the edit command usually means to apply to the entire current line. For example, "<<" means shift current line left; "cc" means replace entire current line; and "dd" means delete entire current line. |
|||
|
|||
*Key Bindings in Editing Modes* |
|||
- While in any edit mode (insert, replace, etc.) there are some keys that are used to adjust behaviour, rather than just to insert text. |
|||
|
|||
[source,bash] |
|||
---- |
|||
ESC - leave edit mode, return to command mode |
|||
^D - move line backwards one shiftwidth. shiftwidth must be set, and either the line must be newly added, or ^T must have been used. |
|||
^T - move all after cursor forwards one shiftwidth |
|||
---- |
|||
==== |
|||
|
|||
.Key combinations |
|||
[options="header,footer"] |
|||
|======================= |
|||
|Key|Action | Followed by |
|||
|a |enter insertion mode after current character | text, ESC |
|||
|b |back word | |
|||
|c |change command cursor | motion command |
|||
|d |delete command cursor | motion command |
|||
|e |end of word | |
|||
|f |find character after cursor in current line | |
|||
|i |enter insertion mode before current character | text, ESC |
|||
|m |mark current line and position mark character | tag (a-z) |
|||
|n |repeat last search | |
|||
|o |open line below and enter insertion mode | text, ESC |
|||
|p |put buffer after cursor |
|||
|r |replace single character at cursor | replacement character expected |
|||
|s |substitute single character with new text | text, ESC |
|||
|t |same as "f" but cursor moves to just before found character | character to find |
|||
|u |undo | |
|||
|w |move foreward one word | |
|||
|y |yank command | cursor motion command |
|||
|z |position current line | CR = top; "." = center; "-"=bottom |
|||
|A |enter insertion mode after end of line | text, ESC |
|||
|B |move back one Word | |
|||
|C |change to end of line | text, ESC |
|||
|D |delete to end of line | |
|||
|E |move to end of Word | |
|||
|F |backwards version of "f" | character to find |
|||
|G |goto line number prefixed, or goto end if none | |
|||
|H |home cursor - goto first line on screen | |
|||
|I |enter insertion mode before first non-whitespace character | text, ESC |
|||
|J |join current line with next line | |
|||
|L |goto last line on screen | |
|||
|M |goto middle line on screen | |
|||
|N |repeat last search, but in opposite direction of original search | |
|||
|O |open line above and enter insertion mode | text, ESC |
|||
|P |put buffer before cursor | |
|||
|Q |leave visual mode (go into "ex" mode) | |
|||
|R |replace mode - replaces through end of current line, then inserts | text, ESC |
|||
|S |substitute entire line - deletes line, enters insertion mode | text, ESC |
|||
|T |backwards version of "t" character to find | |
|||
|U |restores line to state when cursor was moved into it | |
|||
|W |foreward Word | |
|||
|Y |yank entire line | |
|||
|0 |move to column zero | |
|||
|1-9| numeric precursor to other commands [additional numbers (0-9)] command | |
|||
|! |shell command filter cursor motion command, shell command | | |
|||
|@ |vi eval buffer name (a-z) | |
|||
|$ |move to end of line | |
|||
|% |match nearest [],(),{} on line, to its match (same line or others) | |
|||
|^ |move to first non-whitespace character of line | |
|||
|& |repeat last ex substitution (":s ...") not including modifiers | |
|||
|( |move to previous sentence | |
|||
|) |move to next sentence | |
|||
|\| |move to column zero | |
|||
|- |move to first non-whitespace of previous line | |
|||
|_ |similar to '^' but uses numeric prefix oddly | |
|||
|+ |move to first non-whitespace of next line | |
|||
|[ |move to previous "{...}" section | "[" |
|||
|] |move to next "{...}" section | "]" |
|||
|{ |move to previous blank-line separated section | "{" |
|||
|} |move to next blank-line separated section | "}" |
|||
|; |repeat last "f", "F", "t", or "T" command | |
|||
|' |move to marked line, first non-whitespace | character tag (a-z) |
|||
|` |move to marked line, memorized column | character tag (a-z) |
|||
|: |ex-submode ex command | |
|||
|" |access numbered buffer; load or access lettered buffer | 1-9,a-z |
|||
|~ |reverse case of current character and move cursor forward | |
|||
|, |reverse direction of last "f", "F", "t", or "T" command | |
|||
|. |repeat last text-changing command | |
|||
|/ |search forward | search string, ESC or CR |
|||
|< |unindent command | cursor motion command |
|||
|> |indent command | cursor motion command |
|||
|? |search backward | search string, ESC or CR |
|||
|^D |down half screen | |
|||
|^G |show status | |
|||
|^J |line down | |
|||
|^T |go to the file/code you were editing before the last tag jump | |
|||
|^U |up half screen | |
|||
|^Z |suspend program | |
|||
|^[ |(ESC) cancel started command; otherwise UNBOUND | |
|||
|^\ |leave visual mode (go into "ex" mode) | |
|||
|^^ |switch file buffers |
|||
|======================= |
|||
|
|||
|
|||
|
|||
|
|||
|