14. Networking and communication

Aims

My knowledge about the networking is almost zero and I would like to use this opportunity to learn the main principle of internet communication and radio. Previously I used ISP and serial communication before. This week I learned a bit about the USB communication. Furthermore, start using MQTT protocol for internet communication.

Group assignemetn

With the help of our instructors we had a session where we made a MCU node and send the data to a server with mqtt protocol and receive a data from another node and activate an output device (in my case an LED) with the receive data.

wireless communication or OTA (over-the-air)

As I understood all the wireless communications are some sort of radio communications that has been build up on some protocols. Radio, Wi-fi, Bluetooth are the example of this kind of communication but they may use different protocols to send and receive data. Here I used Internet which consist of many communication and networking methods and protocols.

Internet

Here I want to document my understanding from the internet that we use these days more then ever and it is helping us to be connected. When we connect to internet through wi-Fi basically we connecting to our router and from there is a ethernet wire or fiber cable which connect us to our service provider. From there this connection can be any thing until it reaches the receiver in the other side of the network. Also good to have this understanding that all internet is IP addresses (internet protocol address). Imagine that internet network is a city. If you want to go from your place to another place, first you have to be in the city. Here your internet provider give you a place in the internet network with a specific address. Now that you now where you are you can start routing to the address that you want to go. But all you know from where you want to go is a name (DNS). To get the address base on the name you have; you need to look for the address in a address book(DNS server). In this book all the name are mapped to a IP address. When you find the address now you can plan your journey in the city to reach the other point. I hope my analogy help you to relate what is happening in the internet when you trying to reach fabacademy.org. As I mentioned earlier the protocols on internet is varied. To have better understanding of this protocol we need to have a look into OSI model(open system interconnection). This model is a conceptual and tries to suggest a standard for communication of computing system regardless their structure. This model consist of seven obstruct layers:

    1. physical layer
    1. Data link layer
    1. Network layer
    1. Transport layer
    1. Session layer
    1. Presentation layer
    1. Application layer

physical layer is the lowest layer of OSI model. It is responsible for physical data in the network. For example cable, network card, router, etc. The data link is representative of source and destination of the data in the network. MAC(media access control) address and switches are in this layer. In the network layer we have IP addresses and routers that connecting this addresses together. In the transport layer we have TCP and UDP protocol that connect the devices base on their IP addresses. In the session layer we control the start and end of the communication with the devices. In the layer 6 we have presentation that means it converting the data in a understandable form for application. this is the layer that can have encryption. An the last layer is the application where the user communicate together. So for instance when you are trying to reach Send an email:

  • first stage is the email that you wrote and the email address that you want to send it to, etc. and it would get ready to send with SMTP(simple mail transfer protocol).
  • in the next layer which is presentation the data will be converted to a format that would be understandable universally for instance in this case the data would be converted to ASCII. Additional encryption can happen here.
  • In the session layer, the session with the Email server will be started.
  • In the layer four, the transportation will be started. In this case we will use TCP to minimize the packet lost. In this step the source and destination port will be added to the data.
  • In the next layer, the source IP address and the email server IP address(destination) will be added to the data.
  • in the layer six, the source MAC address of the router and host will be added to the data.
  • in the physical layer data will be sent out through ethernet(or any other medium).

after the data reaches the destination, the receiver unwrap the data in the sequence that has been wrapped in the origin point. But we have to keep in mind that although the internet model is explainable with this OSI model but they are not the same. The current internet uses a model called TCP/IP model which consist of 4 layers:

    1. physical
    1. Link
    1. network
    1. Transport
    1. Application

The difference between this model and OSI is that the application, presentation, session all will be included in the application layer of TCP/IP model. the existent protocol for each layer are:

  • physical layer: ethernet, wi-fi, DSL, FDDI
  • Link: L2TP, PPP, MAC
  • network: IP(IPv4,IPv6), ICMP, IPsec
  • Transport: TCP, UDP, DCCP, SCTP, RSVP
  • Application: HTTP, HTTPS, DNS, DHCP, BGP, IMAP, MQTT, PTP, RTP, SSH, TSL

MQTT

MQTT is machine to machine protocol for IoT connection. It designed in way to be light so it can be fit into the macro-chips. Here is the example that we did as group assignment. I am using ESP8266 developed board. The board is reading the data from a potentiometer and sending it through he network and if it receive a data and it is more than an instance it will lighting up a LED. The steps starts from connecting the board to the wi-fi. After that we will need to make a mqtt client which is connected to the mqtt server. Basically here we read a value from one of the pins. After converting the value to a string. Then we transform it to a mqtt segment. by using mqtt client object we will add TCP headers to the data to make it ready for transmission. At the end with the publish method we will send it to the specified server.

code ESP8266

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// SETUP WIFI CREDENTIALS
const char* ssid = "wifiname";
const char* password = "wifiPassword";
const char* mqtt_server = "broker";
const char* mqtt_user = "user";
const char* mqtt_pass = "password";

const int output5 = 5;
const int output4 = 4;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output4, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output4, LOW);
  // PUT THE CODE TO START YOUR SENSORS HERE

}

void loop() {

  if (!client.connected()) reconnect();
  client.loop();

  // Publish every 1000 milliseconds
  if (millis() % 5000 == 0) {

    // READ YOUR SENSOR DATA HERE
    float value = analogRead(A0);

    // Send value as characters
    char msg[50];
    snprintf (msg, 50, "%f", value);
    Serial.print("Publish message: ");
    Serial.println(msg);

    // SET THE TOPIC TO PUBLISH HERE
    client.publish("input/ARMAN", msg);
  }
}

void callback(char* topic, byte* payload, unsigned int length) {

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  String strPayload = String((char*)payload);

  // Serial.println(strPayload.toFloat());
  // Serial.println(strPayload.toInt());

  // USE RECEIVED DATA HERE
  if (strPayload.toInt() > 20) digitalWrite(output4, LOW);
  else digitalWrite(output4, HIGH);

}

void reconnect() {

  // Loop until we're reconnected
  while (!client.connected()) {

    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);

    // Attempt to connect
    if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
      Serial.println("connected");

      // SET THE TOPIC TO SUBSCRIBE HERE
      client.subscribe("output/ARMAN");

    } else {

      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);

    }
  }
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

python mqtt

Here also I tried to communicate by python with the mqtt server. I am just sending a random number. Here we do not need to connect to internet since this value will be sent from our machine. I am just generating a random number instead of sensor value. The client

import paho.mqtt.client as mqtt
import time
import random

mqtt_broker = "netfabbcn.hopto.org"
mqtt_user = "students"
mqtt_pass = "fablabbcnisnice"
broker_port = 1883

def on_connect(client, userdata, flags, rc):
   print(f"Connected With Result Code: {rc}")

def on_message(client, userdata, message):
   print(f"Message Recieved: {message.payload.decode()}")
   # Do something here with the message

def on_log(client, obj, level, string):
    print (string)

def read_sensor():
    sensor_reading = random.randrange(0,1024)
    return sensor_reading

client = mqtt.Client(clean_session = True)
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log
client.username_pw_set(username = mqtt_user, password = mqtt_pass)
client.connect(mqtt_broker, broker_port)


# Subscribe to your topic here
client.subscribe("output/pyarman", qos=1)
client.publish(topic="input/pyarman", payload="Hello from python", qos = 1, retain = False)


# Start looping (non-blocking)
client.loop_start()

while True:
    # Read data here
    sensor_reading = read_sensor()
    # Publish data here
    client.publish(topic="input/pyarman", payload=sensor_reading, qos = 1, retain = False)
    time.sleep(20)

soft access point

I tried to make a softAP with NodeMCU which runs with ESP8266. Basically here we converting the NodeMCU to a virtual router. This device is also can act as server. After that I connect to through the wifi to the node and it render the html response. Here I first connect the ESP8266 to the network as virtual access point. The access point will be wait in the network for any packet for port 80. If it receive such request, it will return a packet with 200 header and a html which will can be rendered in the application level of our device.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char *ssid = "MyESP8266AP";
const char *password = "testpassword";

ESP8266WebServer server(80);

void handleRoot() {
  server.send(200, "text/html", " <h1>Hello from ESP8266 AP!</h1>");
}

void setup() {

  Serial.begin(115200);

  WiFi.softAP(ssid, password);

  Serial.println();
  Serial.print("Server IP address: ");
  Serial.println(WiFi.softAPIP());
  Serial.print("Server MAC address: ");
  Serial.println(WiFi.softAPmacAddress());

  server.on("/", handleRoot);
  server.begin();

  Serial.println("Server listening");
}

void loop() {
  server.handleClient();
}
Fig-1 : finding the WiFi access point
Fig-2 : Rendering the html

NodeMCU Communication

I am trying to make 2 node one client the other server with ESP8266 devBoard. In the server side I am reading the data that has been sent by client and change the position of the servo motor accordingly. In the client side I am reading the value of a potentiometer and sending it to the server through the http protocol.

I am facing a problem you can follow up the in an issue that I raised. would be amazing if you could give me any insight.

To extend the explanation, in the client side the chip will try to connect to the WiFi. if it fail to connect it will go to hibernate. If connected it will send a http packet with the sensor value.

In the server side, after connecting to the network, we will open a server on port 80 in our local network. In the next we will subscribe the packet coming form the client IP. Then we will unwrap the packet to extract the value. Base on the value I will update the position of a servo motor to change its position.

Client Code

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// AP Wi-Fi credentials
const char* ssid = "MyESP8266AP";
const char* password = "testpassword";
const char* host = "192.168.11.4";
// Local ESP web-server address
String data;
// DEEP_SLEEP Timeout interval
int sleepInterval = 5;
// DEEP_SLEEP Timeout interval when connecting to AP fails
int failConnectRetryInterval = 2;
int counter = 0;
float pt;
const int analogInPin = A0;


WiFiClient client;

void setup() {
  pinMode(analogInPin, INPUT);
  ESP.eraseConfig();
  WiFi.persistent(false);
  Serial.begin(115200);
  Serial.println();
  Serial.println("BEGIN");
  delay(500);
  WiFi.begin(ssid, password);
  Serial.println("");
  while (WiFi.status() != WL_CONNECTED) {
    if(counter > 20){
       Serial.println("- can't connect, going to sleep");    
       hibernate(failConnectRetryInterval);
    }
    delay(500);
    Serial.print(".");
    counter++;
  }

  Serial.println("- wifi connected");
  Serial.println("IP Address: ");
  Serial.println(WiFi.localIP());
  readSensor();
  Serial.println("- send GET request");
  sendHttp();
  Serial.println();
  Serial.println("- got back to sleep");
  Serial.println("");
  Serial.println("**************************");
  hibernate(sleepInterval);
}

void sendHttp() {
  if(client.connect(host,80)){
    String url = "/update?pt=";
    url+= String(pt);
    client.print(String("GET")+url+"HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"Connection: keep-alive\r\n\r\n");
    delay(10);
    Serial.println("Response:");
    while(client.available()){
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
  }

}

void readSensor() {
  delay(200);
  pt = analogRead(analogInPin);
  if (isnan(pt)) {
    pt = 0.00;
  }
  Serial.println("- potentiometer read : "+String(pt));
}


void hibernate(int pInterval) {
  WiFi.disconnect();
  ESP.deepSleep(10 * 600000 * pInterval, WAKE_RFCAL);
  delay(100);
}

void loop() {}

Server Code

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Servo.h>
const char *ssid = "MyESP8266AP";
const char *password = "testpassword";
IPAddress ip(192, 168, 11, 4);
IPAddress gateway(192, 168, 11, 1);
IPAddress subnet(255, 255, 255, 0);

ESP8266WebServer server(80);
Servo myservo; // create servo object to control a servo
//static const uint8_t D2   = 4;
float pt;
void setup(void) {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(ip,gateway,subnet);
  WiFi.softAP(ssid,password);
  Serial.begin(115200);
  Serial.println();
  Serial.println("IP Address: ");
  Serial.println(WiFi.localIP());
  delay(10);
  server.on("/",handle_index);
  server.on("/update",handle_update);
  server.begin();

  myservo.attach(D2);
}
void handle_index() {
  server.send(200, "text/plain", String(pt));
}
void handle_update() {
  pt = server.arg("pt").toFloat();
  Serial.println(pt);
  server.send(200, "text/plain", "updated");
  servo(pt);
}

void loop(){
  server.handleClient();
}
void servo(float pt){
  if (pt>0 && pt<1024){
    float pos = map(pt,0,1023,0,180);
    myservo.write(pos);
  }
}

wire communications

Wire communication is something that we got involve so many times during the course up until know. The most common one is serial communication which I used on my touch pad to communicate with a interface. I have tried ISP to program my stepper driver and my charlieplexing board.

ISP

In this section I have tried the SPI communication between two arduino uno board. I used SPI.h Library and put the arduino as ISP. ArduinoISP I upload the code for the master but I had this error. error: avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xe5

then I figure out because the reset pin should not be connected. but there is still a logical error since I do not have any response from the slave. I am trying to look for more examples to understand the problem. I found some problem in wiring. The connection of MISO, MOSI was wrong!

Maste code
include<SPI.h>                             //Library for SPI
#define LED 2
int buttonvalue;
int x;
int incomingByte = 0;

void setup (void)
{
  Serial.begin(115200);                   //Starts Serial Communication at Baud Rate 115200

  pinMode(LED, OUTPUT);                   //Sets pin 7 as Output

  SPI.begin();                            //Begins the SPI commnuication
  SPI.setClockDivider(SPI_CLOCK_DIV8);    //Sets clock for SPI communication at 8 (16/8=2Mhz)
  digitalWrite(SS, HIGH);                 // Setting SlaveSelect as HIGH (So master doesnt connnect with slave)
}

void loop(void)
{
  byte Mastersend, Mastereceive;

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.println(incomingByte);
  }
  if (incomingByte == 48)
  {
    x = 1;
  }
  else
  {
    x = 0;
  }

  digitalWrite(SS, LOW);

  Mastersend = x;
  Mastereceive = SPI.transfer(Mastersend);

  if (Mastereceive == 49)
  {
    digitalWrite(LED, HIGH);
    Serial.println("Master LED ON");
  }
  else
  {
    digitalWrite(LED, LOW);
    Serial.println("Master LED OFF");
  }
  delay(1000);
}
slave code
//SPI SLAVE (ARDUINO)
//SPI COMMUNICATION BETWEEN TWO ARDUINO
//CIRCUIT DIGEST
//Pramoth.T

#include<SPI.h>
#define LEDpin 2

volatile boolean received;
volatile byte Slavereceived, Slavesend;
int buttonvalue;
int x;
void setup()

{
  Serial.begin(115200);

  pinMode(LEDpin, OUTPUT);                // Setting pin 7 as OUTPUT
  pinMode(MISO, OUTPUT);                  //Sets MISO as OUTPUT (Have to Send data to Master IN

  SPCR |= _BV(SPE);                       //Turn on SPI in Slave Mode
  received = false;

  SPI.attachInterrupt();                  //Interuupt ON is set for SPI commnucation

}

ISR (SPI_STC_vect)                        //Inerrrput routine function
{
  Slavereceived = SPDR;         // Value received from master if store in variable slavereceived
  received = true;                        //Sets received as True
}

void loop()
{ if (received)                           //Logic to SET LED ON OR OFF depending upon the value recerived from master
  {
    if (Slavereceived == 49)
    {
      digitalWrite(LEDpin, HIGH);        
      Serial.println("Slave LED ON");
      delay(500);
      x = 0;
    } else
    {
      digitalWrite(LEDpin, LOW);        
      Serial.println("Slave LED OFF");
      delay(500);
      x = 1;
    }

    Slavesend = x;
    SPDR = Slavesend;                           //Sends the x value to master via SPDR
    delay(1000);
  }
}
Fig-3 : ISP connection of Arduino

Final project contribution

In my final project I have used I2C to communicate between my boards and main motherboard. you can check my documentation on that in the Following link.


class note:

Wire communication

serial communication

USB communication

parallel cable

clock signal coordinate the data read and send

Synchronous/Asynchronous communication

Asynchronous: Serial communication software serial communication(bit banging) UART CRC check

V-USB https://en.wikipedia.org/wiki/Differential_signaling

Synchronous: Master/slave I2C: SDA SCL


wireless communication: radio transmissions wi-fi

antenna: different design for different purpose

radiation pattern Gian of the antenna

monopole Helical antenna patch antenna

Frequency spacing AM-FM-SIGNAL

Wi-fi Analyzer

through the air communication

is there any regulation of using protocols?

Network and osi

what happens when you type google in your browser

OSI model