Showing posts with label ethernet. Show all posts
Showing posts with label ethernet. Show all posts

Tuesday, May 3, 2016

Minecraft on Raspberry Pi Zero using OTG USB Ethernet connection with RealVNC server and client


In my previous post I connected to a Raspberry Pi 3 using RealVNC to connected over Ethernet.
To achieve this you would need:
Laptop
Raspberry Pi
PSU for Pi
Ethernet cable

What if you could replace the PSU and Ethernet with just a microUSB cable and replace the Pi3 by a PiZero.
Well, this is absolutely possible and quite simple due to the hard work of a number of people including Andrew Mulholland who created a guide on setting up Ethernet over USB using OTG that I hope to make even more simple here. Then it's a matter of installing RealVNC to get the Raspbian desktop on your laptop.

OTG stands for On-The-Go or it's full name USB On-The-Go
Put simply OTG allows a USB device to act like a host and have peripherals  such as keyboard and external storage attached to the device or act like a slave so it can be a network device or a mass storage device.
This is most used on phones an tablets where it's great to be able to plug in a USB stick and access the files (host) or plug the phone into your computer and download the files (slave)

For OTG is enabled by the ID-pin which is available on the PiZero as the USB port is directly connected to SOC and it uses a microUSB connector which has the extra pin for the ID.

Back in December Andrew posted a guide on setting up OTG.
It includes a lot extra information that is worth reading and understanding, but here I want to just do the facts and steps needed to enable Ethernet over USB.

I'm assuming you have already installed Raspbian on your PiZero 

Next you need your PiZero to be connected to the network to be able to download and install some files. For this I used an Wii USB Ethernet adapter.  This adapter is supported by default. They're about £10 on eBay.  Just search Wii USB Ethernet.

With the PiZero connected to the network I found the Pis IP address using Fing on my phone.
With the IP address known I used putty to ssh in. (Yes, this is the correct link for downloading)

Once logged in do the usual housekeeping.
sudo raspi-config to expand the filesystem and set GPU memory to 128MB
sudo apt-get update
sudo apt-get upgrade

Then it's a matter of running the following commands one after another to get Ethernet over USB set up. Andrew's guide explains what they do and also the other OTG options available.


sudo BRANCH=next rpi-update

echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt

echo "dwc2" | sudo tee -a /etc/modules

echo "g_ether" | sudo tee -a /etc/modules

echo -e "interface usb0 \nstatic ip_address=169.254.64.64" | sudo tee -a /etc/dhcpcd.conf

Now Ethernet over USB should be set up.

Next RealVNC server needs to be installed.  The guide for installing the latest Alpha that supports Minecraft can be  found here. https://github.com/RealVNC/raspi-preview

With the relevant commands being:
curl -OL https://github.com/RealVNC/raspi-preview/releases/download/5.3.1.18206/VNC-Server-5.3.1-raspi-alpha1.deb

sudo dpkg -i VNC-Server-5.3.1-raspi-alpha1.deb

sudo systemctl enable vncserver-x11-serviced.service

These install RealVNC server and enable it as a service that starts at boot up.

Shutdown your PiZero using
sudo shutdown 0

Unplug the cabled.
Plug single microUSB cable into the USB port on the PiZero and the other end into your laptop USB port. The PiZero uses so little power it can safely be powered from the laptop USB with no issues.
Mine laptop is running Windows 10 and the device is automatically detected and the drivers installed.  I didn't have to do anything.
This creates a new Ethernet device.

Download and install RealVNC Viewer 

Run RealVNC Viewer on your laptop and enter the fixed IP address of 169.254.64.64 used when setting up the PiZero.
It will ask for your login. On mine it defaults to the laptop username. so, just change to pi/raspberry assuming you haven't changed it.

RealVNC should now login to the PiZero.
It's that simple.

RealVNC recommend some optimisation that I definitely found to improve performance.

On the VNC Viewer toolbar (top of the Window), click the Options button.
Click Advanced..., then the Expert tab.
Set PreferredEncoding to JPEG, AutoSelect to False, and ColorLevel to Full

These changes really make RealVNC smoother.

If using Minecraft you have to make one more selection.
Press [F8] to go back to the menu and select Relative Pointer Motion
Then start Minecraft as normal.
All should work perfectly.

You will notice that the RealVNC window is quite small this is because there is no resolution details set by a display so the Raspberry Pi defaults to 640x480 as the safest mode.

To increase the resolution you have to make some minor changes to config.txt
RealVNC give full details on this on the following support page

But to put it simply to set the resolution to 800x600 do the following

Open a terminal window
cd /boot
sudo cp config.txt config.txt.backup
sudo nano config.txt

This makes a backup of config.txt and then opens it with nano

Remove the # in front of hdmi_force_hotplug and set it to 1
hdmi_force_hotplug=1


Enter the following line into config.txt

hdmi_ignore_edid=0xa5000080


No idea what it does and even RealVNC describe it as better safe than sorry.  I've run without it and it worked.

Remove the # in front of hdmi_group and set it to 2.
hdmi_group=2

Remove the # in front of hdmi_mode and set it to 9 which is the value for 800x600.
You can look up all the values and adjust according to your needs on the elinux.org page

Press [CTRL]-[x] to exit.
Select y for saving changes and then press [Enter]

Now your config.txt is up to date.

Restart the Raspberry Pi and it will restart with a resolution of 800x600 rather than 640x480 making everything a little easier.
If you want a higher resolution then hdmi_mode=16 is 1024x768 and hdmi_mode=39 is 1360x768

Finally, here is a (low quality recorded from my phone) video of it all running. You can see the speed is good and even programming in Python works well.


Sunday, May 1, 2016

Using only Ethernet cable to connect Windows computer to Raspberry Pi

The Raspberry Pi is designed to be used as a standalone computer only needing a monitor, keyboard and mouse to function.

There are many guides on how to SSH or VNC into the Raspberry Pi with the network set up usually using a router.

Well, what if you don't have a router because you're at an event or you don't want to put your Pi on the network.  It's fun at a Raspberry Jam to see all the Raspberry Pi's with the same name and the same username and password on a network.

For this situation there is a really simple solution.  You give the computer's Ethernet port a fixed IP and you do the same on the Pi.
The great thing with this is the computer and the Pi can still connect to the available network over wifi and if available connect to the internet. 


I use this configuration a lot for simple python development where a full GUI isn't needed and since my ability to remember things is limited access to the internet from my laptop is essential for tips and trouble shooting.


For this to work the IP addresses you give the Ethernet ports cannot be on the same subnet as the router (if there is one)
To check this on Windows do an ipconfig

You'll get something like below which shows the Wireless has an IP address of 192.168.0.11 with a subnet mask of 255.255.255.0 and a gateway of 19.168.0.1

The subnet mask says what range is usable.
In this case 192.168.0.1 - 192.168.0.255 are all in the subnet so are part of this routers control. 
You can limit the IP controlled by the router, but for this it's safer to assume ALL IP addresses from 1-255 are out of bounds. There are more than enough other IP addresses to use safely

Windows IP Configuration

Ethernet adapter Ethernet:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Local Area Connection* 3:
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Local Area Connection* 5:
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Wi-Fi:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::501b:b10b:e1c4:62ff%5
   IPv4 Address. . . . . . . . . . . : 192.168.0.11
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

Tunnel adapter isatap.{70D5B1BF-BEE1-475B-9752-73772D3EA37A}:
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Tunnel adapter Teredo Tunneling Pseudo-Interface:
   Connection-specific DNS Suffix  . :
   IPv6 Address. . . . . . . . . . . : 2001:0:5ef5:79fb:2c33:3c3f:3f57:fff4
   Link-local IPv6 Address . . . . . : fe80::2c33:3c3f:3f57:fff4%2
   Default Gateway . . . . . . . . . : ::


With this kind of set up I usually go for the range 10.0.0.X
Setting the IP for the computer to 10.0.0.100 and then the Pi's use IP addresses from there up.


Setting IP address on Windows Computer

Go to the Setting and select [Network and Internet]


Then select Ethernet and [Change adapter settings]







Right Click on the Ethernet adapter and select [Properties]



If you're not logged in as Administrator rights then you'll be asked to enter your Administrator password.

Once done select Internet Protocol Version 4 (TCP/IPv4) and click [Properties]


By default it's probably set to Obtain IP address automatically with the same for DNS

Click [Use the following IP address:] and enter the IP address you wish to use on the computer.
As I mentioned I set  mine to 10.0.0.100

When you click OK it might say a subnet isn't set and set a default of 255.0.0.0.  Just accept the subnet.  It is used to keep IP addresses in organised groups so it doesn't matter what it is for our purposes as long as our 2 IP addresses are included, which they will be.



Then just click OK and close all the windows that have been opened.  All is now set for the computer.

For the Pi side  you will either need a monitor, keyboard and mouse or to have a router to connect to the Ethernet or have WiFi setup as this method uses the GUI desktop tool. 


I'm using RealVNC as I've been playing with Minecraft over VNC
Connect using RealVNC to your WiFi or provided IP address for your Ethernet port.

Top right in the task bar right click on the network/wifi indicator and select [Wifi network (dhcpcdui) Settings]



This will open the Network Setting tool

It opens with the Configure: Interface option but with nothing selected. In the blank drop down select eth0

Automatically configure empty options should be ticked with all fields empty.
Now type the IP address you want to use in the IP Address: box.  For this one I used 10.0.0.102

Then [Apply] and [Close]

At this point I usually restart the Raspberry Pi and connect the Ethernet port directly to the laptop.
Of course my VNC session will disconnect. So I will have to connect again.

Now if I run ipconfig on the laptop I get the following where the Ethernet IP is 10.0.0.100 (result)

Ethernet adapter Ethernet:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::b0ac:5dbe:415b:e7e3%11
   IPv4 Address. . . . . . . . . . . : 10.0.0.100
   Subnet Mask . . . . . . . . . . . : 255.0.0.0
   Default Gateway . . . . . . . . . :

Wireless LAN adapter Wi-Fi:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::501b:b10b:e1c4:62ff%5
   IPv4 Address. . . . . . . . . . . : 192.168.0.11
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1


Reconnect RealVNC with 10.0.0.102 as the Raspberry Pi IP address and everything should work.
Now no need for a router, or a WiFi. But if you have WiFi then the computer and Pi can still connect to the Internet using WiFi while maintaining their direct connection to each other over the Ethernet so wget and other updates can still be done.

The great thing with this is also that since each Pis Ethernet connection will be on a different network if you have 10 laptops with 10 Pis you can do this setup on one Pi and then dd the microSDs on to the others and they will all work with no conflict.




Saturday, August 25, 2012

Arduino, Ethernet, Ethercard, XAMPP web server, PHP web page controlling 2 LEDs

[UPDATE 17 Sept 2012 - I have modified the XAMPP webserver code  get the details for the Arduino(s) from a database.  See the updated version here

I tinkered a while back with using a web server to control and Arduino over a serial connection and then I got an ENC28J60.  A really cheap Ethernet socket that can work with the Arduino. It uses the Ethercard community provided library.

My goal was to find a way to turn on and off LEDs which can later become Servos once I've done the hard coding from a web server that then connects to the Arduino over Ethernet.

Using this method the web server and the Arduino don't have to be near each other and even more importantly they don't need to be physically connected.

After a bit of research and trial and error I have something working.
This example presents a simple PHP based web page on the web server with the options to turn on or off 2 LEDs. (sorry for the gaudy colours in the video I thought it would be good to match the LED colours with the menus.

When you click a button on the web page it calls itself with a POST variable set.
The PHP page then interprets this and does an fopen() to the Arduino to do the requested action.

By doing an fopen() the actual connection to the Arduino is not shown on the web page.

The fun with this is that it could be expanded to control more pins easily and also control more than 1 Arduino.



PHP Code on the Server


<!--
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pin2 and Pin4 on
the Arduino using a web server as the interface.
The web page is served with the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not needed and also the commands to control the Arduino is not 
shown publicly when compared to using the Arduino as the web server itself and using a GET REQUEST.

By doing it this way you have more control over the Arduino and the web interface.

NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.

-->

<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php

// Check of LED2 is set.  If it is use it
if (isset($_POST["LED2"]))
{
$LED2= $_POST["LED2"];
//echo "<b>$LED2</b>";
}
else
{
$LED2 ="";
}
if ($LED2 == "ON")
{
// Set led2 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED2=ON", "rb");
}
else if ($LED2 == "OFF")
{
// Set led2 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED2=OFF", "rb");
}

// Check of LED4 is set.  If it is use it
if (isset($_POST["LED4"]))
{
$LED4= $_POST["LED4"];
//echo "<b>LED4 is $LED4</b>";
}
else
{
$LED4 ="";
}
if ($LED4 == "ON")
{
// Set led4 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED4=ON", "rb");
}
else if ($LED4 == "OFF")
{
// Set led4 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED4=OFF", "rb");
}

?>
<!-- LED2 FORM -->
<table>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off the LED2</font></H4></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>

<table>
<tr><td colspan="2"><font size="4" color="green">Turn on and off the LED4</font></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>


</body>
</html>

Arduino code

/*
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

Script to allow the controling on the Arduino over Ethernet using an ENC28J60 Ethernet socket and the Ethercard library
Assigning Static IP for the Arduino so I can know exactly which Arduino I am controlling
For this example the request is either http://192.168.1.5/?LED2=ON or http://192.168.1.5/?LED2=OFF
These can be called directly but then the Arduino would have to be the web server and present back the web page
with the option to turn the LED off or ON

For this example I am controlling the Arduino from a webserver on my PC (XAMP) using a PHP script.

*/
// I took took inspiration from the following 2 examples

// The BackSoon example provided with the EtherCard library
// Present a "Will be back soon web page", as stand-in webserver.
// 2011-01-30 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

// Example from the Internet
// https://github.com/lucadentella/enc28j60_tutorial/blob/master/_5_BasicServer/_5_BasicServer.ino
#include <EtherCard.h>

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = { 192,168,1,5 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

// Using a Variable for the Pin, but it is not necessary 
const int ledPin2 = 2;
const int ledPin4 = 4;


// Some stuff for responding to the request
char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

// Small web page to return so the request is completed
char page[] PROGMEM =
"HTTP/1.0 503 Service Unavailable\r\n"
"Content-Type: text/html\r\n"
"Retry-After: 600\r\n"
"\r\n"
"<html>"
  "<head><title>"
    "Arduino 192.168.1.5"
  "</title></head>"
  "<body>"
    "<h3>Arduino 192.168.1.5</h3>"
  "</body>"
"</html>"
;

void setup(){
// Set Pin2 to be an Output
  pinMode(ledPin2, OUTPUT);
// Set Pin4 to be an Output
  pinMode(ledPin4, OUTPUT);

// Scary complex intializing of the EtherCard - I don't understand this stuff (yet0  
  ether.begin(sizeof Ethernet::buffer, mymac);
// Set IP using Static
  ether.staticSetup(myip, gwip);
}

void loop(){
  
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

// IF LED2=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin2, HIGH);
    }

// IF LED2=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin2, LOW);
    }

// IF LED4=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin4, HIGH);
    }

// IF LED4=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin4, LOW);
    }

//Return a page so the request is completed.

    memcpy_P(ether.tcpOffset(), page, sizeof page);
    ether.httpServerReply(sizeof page - 1);
  
}

If you want more details on using the ENC28J60 check out my previous post on it.  It gives details on wiring and various libraries for it.