I was recently a guest on 96Boards OpenHours to demonstrate how the Aerocore 2 for Dragonboard 410C can be used to quickly and easily build a working quadcopter. I even powered it up and tested it out indoors live.
If you want to see what happened, check out the YouTube video. The test flight happens at around the 40-minute mark.
Drones are awesome and not that hard to set up. You can follow along with me if you’re building your own. Once you’ve got your rig put together, then you can start adding software to the Dragonboard — or Any 96Boards CE SBC — to turn it into a self-piloting, obstacle-avoiding, object-following marvel of automation… or whatever it is you plan to do with it.
To find out more about the Aerocore 2 for Dragonboard 410C, you can read my previous post or watch this promo video.
The Parts
The first step in building your quadcopter is to make sure you have all of the hardware you’ll need. Here’s what I had on-hand:
There was no CSI camera working on the test rig so a Logitech C920 HD webcam was used instead.
Some way of mounting the Dragonboard to the drone frame
Zip ties, screws, risers, etc.
Xacto knife, screwdrivers, soldering iron, etc.
You know you work somewhere cool when you can assemble a drone from hardware lying around the office.
The Prep
To keep this post brief, I’m going to glaze over the following steps. They’re fairly straightforward and unrelated and ubiquitous in MAV deployment so there are plenty of instructions available on the web.
Assemble your drone kit.
Do not attach the rotor blades yet. You really don’t want your drone unexpectedly taking flight in the middle of your office/house/garage.
The 12V battery connector and regulator on the Aerocore can handle the main battery’s output but there is no built-in connector on the drone or the battery.
You can solder some jumper wires onto one of the motor power terminals on the base plate of your drone (circled in green here)
Make sure you’ve flashed your Dragonboard with Linux. Linaro’s Debian 16.09 was used for this demo.
Build QGroundControl.
In order to stream video from your MAV you will have to build QGroundControl from source, as it’s not included in the pre-built binaries.
Make sure you have libgstreamer1.0, gstreamer1.0-tools and libgstreamer-plugins-base1.0-dev installed.
(UPDATE: Since the original project was completed, something about the pymavlink pip package has changed and will no longer install dependencies correctly. therefore, add python-lxml to your apt-get command before installing pymavlink and mavproxy)
Put It All Together
Now the fun stuff can begin! It’s time to get everything hooked up and ready to fly.
Step 1: Attach your boards
With this thing going up in the air, you won’t want your hardware sliding around at all so it’s good to put some thought into how your boards are mounted. The chassis I’m using doesn’t have what I’d call a universal mounting system, so I made my own. The box for an Intel Edison turned out to be just the right size and very sturdy. I’ve already been using one on the rover in my RTK project to house a Beaglebone Black.
Some zip ties, screws and risers quickly transformed the cardboard box into a mounting bracket for my Dragonboard. A touch of shameless self-promotion and it’s ready.
Board goes on brackets, Aerocore on board. I used a bit of electrical tape to hold the receiver in place and was ready to wire it up.
Pro-Tip:
MAVs tend to have alarm buzzers, used to indicate low battery and signal loss. This is very important when in flight, but when you’re setting everything up it can be really annoying. Thankfully, the buzzer on the Aerocore 2 has a bypass circuit. After soldering a 2-pin header on the underside of the Aerocore, directly underneath the buzzer, you can use a jumper to deactivate the alarm. For obvious reasons, I don’t recommend hard-wiring the alarm bypass. The picture to the right should help you find the two vias to connect.
Step 2: Connect Wiring
One benefit of using a box as a mounting bracket is that it has proved to be the ideal place to hide excess wiring. I cut a small opening in the bottom of the box and fed all of my wires in and through. I got my hands on a webcam and managed to squeeze its base and cable in there too. I labeled the following image so you can see where the various connections are.
Not having previous experience with MAVs, I had no idea what order to hook the electronic speed control PWMs in. It took me a while, but I figured it out. I put together an infographic for the rest of the amateur MAVers so that you don’t have to struggle like I did.
Step 3: Software
The final pre-flight step is to configure your software. There are three steps:
Flash PX4 firmware to the MCU
Start data pipeline on the Dragonboard
Calibrate on-board sensors
QGroundControl makes programming and configuring your drone a snap. Open up the program and go to the setup tab (). Along the left-hand side will be a button labeled “Firmware”. When you click on this button and then connect the Areocore 2 MCU’s “stm console” via USB, QGC will guide you through the flash process.
The rest of the pre-flight work can be done over WiFi on the Dragonboard. Going wire-free will also make calibration a little easier.
Disconnect the USB cable from your Aerocore and connect the battery. Once the MCU and Dragonboard boot, SSH into the Dragonboard and enter the following command:
Where xxx.xxx.xxx.xxx is the IP address of your PC.
Once the MAVlink command interface comes up on the Dragonboard, QGC should be able to connect to your drone. If it does not connect correctly, you may have to add a UDP connection to QGC’s settings. The setup screen should look simmilar to the following screenshot:
If this is the first time your Aerocore has been configured, the cicles that appear green in this shot will be red and you will not be able to deploy your drone until they all appear green.
Configuring your drone and calibrating the sensors is very straightforward thanks to the self-explanatory interface in QGC. Click on each item along the left-hand side in turn — apart from “Firmware”, which you have already done — and follow the on-screen instructions. Once all the lights are green, you’re ready to fly.
The final, and completely optional steps are getting the camera feed from the Dragonboard to QGC, and attaching a Pre-GO GPS module.
Adding a GPS module is very easy. Once it’s connected, it will work right away. Connect it to the 5-pin molex connector next to the DSM satellite receiver connector. Power down your drone and plug the module in using the included cable, and it’s ready. I added mine last thing right before the live test flight and it worked with no set-up required.
The video streamer, like the MAVlink proxy, is a single command on the Dragonboard:
With both the proxy and the video feed running on the Dragonboard, your flight screen will look something like this:
If you have added a Pre-GO GPS module, your drone’s location will appear in the navigation map seen here in the inset. You can switch the primary view between the video stream and the navigation map by clicking on the inset in the bottom left-hand corner.
Project By: Matthew May & Brendan Harlow for Champlain College SEC-440
Introduction
The goal of this project is to create a private secure portable cell network utilizing basic technologies for mobile phones that can be easily deployable in any situation. In the event of an emergency, commodity cell networks can easily become severely congested and overwhelmed. Having the ability to set up secure and reliable communications for civilians or law enforcement can save lives, facilitate responses, and provide confidence in decision making.
The radio system that we are using for the cell phones to communicate with is the GSM protocol (Global System for Mobiles) more commonly used by cellular provider such as AT&T and T-Mobile. To broadcast the radio system, we are going to be using a Software Defined Radio (SDR) device called the BladeRF (external). This hardware is controlled by the Raspberry PI (small single-board computer) (external) using YateBTS (external) which is software that implements functions and protocols of both the radio access network and the core GSM network to allow cell phones to communicate using voice, text, and data. The Raspberry PI is instrumental to reach our goals of portability due to its size, low power usability, and cost over alternatives.
Prerequisites
To deploy the portable cell network using our instructions you’ll need the following:
Raspberry Pi (We used a 3rd Generation Model B Pi)
MicroSD Card (32GB Recommended)
Nuand BladeRF (We used the BladeRF x40, the smaller card offered by Nuand)
SSH enabled on the Pi (For ease of use, Terminal works fine too)
GSM and SIM card compatible phones
SIM cards (sysmoSIM-GR2)
Ethernet Cable (If you desire the phone’s to have local internet connectivity)
Plug-in the Ethernet, Power Supply, and Keyboard to the Pi and then plug the power adapter into the wall. When you reach the login screen login with the default credentials
Username: pi
Password: raspberry
Run
sudo raspi-config
Change Keyboard Layout
Scroll down to ‘Localisation Options’ and press ‘Enter’
Scroll down to ‘Change Keyboard Layout’ and press ‘Enter’
Scroll down to ‘Other’ and press ‘Enter’
Scroll down to ‘English (US)’ and press ‘Enter’
Scroll to the very top to ‘English (US)’ and press ‘Enter’
Hit ‘Enter’ to accept the defaults on the next two screens, since they don’t apply.
When you get past the last two steps you will be returned back to the main menu.
Enable SSH
Scroll down to ‘Interfacing Options’ and press ‘Enter’
Scroll down to ‘SSH’ and press ‘Enter’
Scroll to ‘Yes’ and press ‘Enter.’
On the next screen, press ‘Enter’ to go back to the main menu.
When you’ve reached the main menu, scroll to the right and select ‘Finish,’ then press ‘Enter’
When back at the terminal, run the command below to enable the configured settings.
sudo reboot now
Network Deployment
To make your life easier, SSH to your Raspberry Pi. Note your Pi’s IPv4 address from the command below:
ifconfig eth0
On another computer, utilize a terminal application and run:
ssh pi@[INSERT PI IPV4 ADDRESS HERE]
Once prompted for credentials, again, enter:
Username: pi
Password: raspberry
Now we are interacting with the Pi remotely.
Let’s start gathering what we need for deployment.
# Download the script from GitHub
wget https://raw.githubusercontent.com/MBRO95/PortableCellNetwork/master/PortableCellNetwork.sh
# Make the downloaded script executable
chmod +x ./PortableCellNetwork.sh
The script will check to make sure you’re running as root, so make sure you don’t leave out the ‘sudo’ portion of the commands below.
To run the script without logging its output, issue:
sudo ./PortableCellNetwork.sh
To run the script while logging its output, issue:
sudo ./PortableCellNetwork.sh | tee install.log
The script will query you for a network name
Provide one and confirm it
OR
press ‘Enter’ to accept the default name of ‘DuaneDunstonRF’
Confirm your network name
The script will now initiate the installation and configuration process. This will take close to an hour so you can go find something to do in the meantime.
When the script is nearing completion it will query for a new user password for the ‘pi’ user.
Enter and re-enter this password to change from the default for added security.
When the script completes it will report how much time it took to run and wait for a keypress to reboot.
Press any key to reboot the pi.
You will be rebooted into a desktop environment, simply select the ‘Default Configuration’ option at the pop-up that launches at first boot.
A startup script titled ‘StartYateBTS.sh’ will await you in ‘/home/pi’ and will start the cell network processes.
To boot the startup script it is imperative that it is run in interactive mode by passing the ‘-i’ flag after the script name, like below:
sudo ./StartYateBTS.sh -i
Once started, this script will:
Open a terminal window reporting the Yate (cell network) status
Open a Firefox browser window that will navigate to YateBTS (web-based cell network configuration)
Here you can view/modify network configuration settings and manage/write SIM cards for devices.
Phone Deployment
To join a compatible phone to the cell network, SIM cards need to be deployed to work with the correct settings. YateBTS uses a utility called PySIM, a python tool for programming SIM cards. In the installation script PySIM is already set up as the correct version that supports the SysmoSIM-GR2 card type. To start, make sure that the compatible SIM card writer is inserted into the Raspberry Pi with the SIM card to program already in it.
Open the tab called Manage SIMs as shown below and make sure that the Generate random IMSI setting is checked and the Insert subscribers is unchecked. The insert subscribers setting will break the functionality of the cell network and is recommended to avoid unless there is a fix for it.
The next step is to check that the correct settings have been set in the Advanced drop down bar. Make sure the Operator name reflects the correct setting that was chosen for the cell network. Otherwise use the default settings and hit save.
The screenshot below shows an example output that the SIM programming was successful. And lastly that the deployed SIM card shows in the Manage SIMs list.
After inserting the SIM card into the GSM phone and powering on, YateBTS will send a welcome message with the assigned number for the phone as shown in the screenshot below. To troubleshoot if the Android phone is not connecting to the cell network properly, open the dialer application and type *#*#4636#*#*. A menu will appear and in the phone information tab, select the preferred network type to be GSM only and restart the phone.
Security Overview
A security model was implemented in our installation script based on the Center for Internet Security (CIS), which is a highly reputable source for best practice information security. The script incorporates a benchmark model designed for Debian 8 operating system. The Debian 8 operating system is the closest relating Linux distribution to the Raspberry Pi image, therefore we decided that this model was the best choice to use for reference. Originally, we did run into a set back with the security functionality of the Raspberry Pi because it does not support custom partitions that can implement security controls, such as full disk encryption and partition modifiers that deny arbitrary executions and protect against attacks that fill up disk space. The goal of the security script was to implement as many controls as we could while keeping the functionality of the Raspberry Pi operating system and the Yate software.
The model follows the practice of disabling anything that is unnecessary to the functionality of the system to reduce the potential attack surface. Performing periodically updates and patches to fix security flaws can be a challenge for a system that is designed to be mobile and in areas where there may not even be access to the Internet.
Update the operating system
Rationale: Periodically patches contain security enhancements, bug fixes, and additional features for functionality.
sudo apt-get -y dist-upgrade
Enable sticky bit on all world writable directories
Rationale: Prevent unauthorized users from modifying or renaming files that belong to a different owner. echo “Setting sticky bit on world writable directories”
Rationale: The linux kernel supports uncommon network protocols that are unneeded for what our goals are for this project. Therefore they should be disabled.
Rationale: A core dump is the memory of an executable program. It is generally used to determine why a program aborted. It can also be used to glean confidential information from a core file.
Rationale: The default password needs to be changed from raspberry. Strong passwords protect systems from being hacked through brute force methods. Password set cannot be a dictionary word, meet certain length, and contain a mix of characters.
passwd pi
General Remarks & Useful Notes
Real-world range testing:
~60’ between phones through walls
~100’ between phones open hallway
Useful directories:
Path to shared files directory
/usr/local/share/yate
Path to conf files directory
/usr/local/etc/yate
Path to user files directory
/root/.yate
Path to modules directory
/usr/local/lib/yate
Testing
The Yate NIB setup includes an ELIZA chat bot that you can communicate with by sending SMS messages to 35492.
This is a good way to test use of a single device.
mrtInit(__SYSTEM_CLOCK / 1000); // multi-rate timer for 1ms
}
int main() {
init();
mrtDelay(100);
deepPowerDownWithWakuUp(60 * 1000, 0); // wake up after 30sec, disable wake up pin
}
I am currently working on a vehicle-installed Arduino project. The device is designed to be powered constantly and I decided to use the car battery as the constant power source. I am designing the device for low power consumption, consuming 50mA or less, ’cause who wants to get stuck with a flat battery, right?
Car battery typically provides 7 to 15 volts, but some standards mention that 40V spikes are possible. Car battery voltage is normally around 12V but drops to ~7V when you are cranking up the engine and it goes up to ~14V when the engine is running and the battery is being charged. Since we don’t want our device to reset during crank-ups we would like to perform conversion of input voltage of 7 to 20 volts to a fixed 5 volts output that the Arduino Uno expects.
Voltage regulators
The Arduino Uno has a voltage regulator on board which we could use. It is recommended for voltages between 7 and 12 volts. This means that we would have to lower the car battery high voltage first with an external component before we can feed it in the Arduino Uno board. Unfortunately, that alone would not solve our problems as it would not address our efficiency requirements.
The issue with using the voltage regulator is that the regulator is wasteful. Any extra voltage that needs to be dropped is converted to heat. The formula for efficiency is eff(reg)=Vout/Vin. A voltage regulator has some advantages too, one of them is stability, which means it can keep a very stable and accurate output voltage. Another advantage is its compact size.To perform an efficient conversion, we would have to use a switching power supply, specifically a buck converter, which will step down the voltage for us. A buck converter will turn the input on and off quickly as much as needed to provide the required voltage and power at the output. The rest of this article will compare six different step-down (buck) modules. If you are not familiar with how a switching-mode step-down converter works, read this article which also compares some modules at higher loads.
Candidate modules
One implementation that I considered is to drop the battery voltage to around 7 volts and then power the Arduino through its voltage regulator. The advantage is a more stable voltage for the Arduino, however, there would be waste of energy of 1-eff(reg)=1-5/7=28%. Furthermore, every conversion process requires some margin between Vin and Vout, so by having two stages it becomes difficult for us to support the lower end of the car battery voltage range, creating potential issues with resets during engine cranking.
So I ended up looking for modules that can take the car battery range and output 5 volts. This could be an adjustable module or one fixed at 5 volts. I would connect those modules to an Arduino USB port (preferred due to additional protections present there) or directly to an Arduino 5V pin. This means that there is some preference to modules with a built-in female USB output port, though adapters or converter cables can be made to compensate for lack of it.
Modules
The modules I tested originate from the Far East and most of them were bought on eBay for between 1 and 2 USD (including shipping). This means that most of them don’t have a clear model number or a manufacturer name. I will come up with a short name for each module so I can mention them easily. I acknowledge that the quality of the photos could be better. I tried my best with the equipment I had available. Also note that each photo is at it’s own scale. Here are the modules in no particular order.
Cigar
This adapter has a cigar lighter plug on one end and is built for plugging into to the cigar lighter socket in a car. The output socket is a female USB port. Such modules are sold to end users for charging USB devices in a car. I have no idea where I got this, but I found it in my parts bin, took it apart and used it in this research.
Since such converters are sold to end users, their listings typically don’t show a photo of the PCB, so it is a roulette with regards to what chip and efficiency you are getting.
Adjustable
This adapter was sold on eBay as “DC-DC Adjustable Step-down Power Module LM2596 4.75-24V To 0.93-18V”. In reality, there is no LM2596 chip there, something that shouldn’t be a huge surprise for eBay shoppers out there. It IS an adjustable step-down module which is great for prototyping. You adjust the output voltage with the multi-turn potentiometer. The input and output connectors are screw terminals and you can see I have connected them to a barrel plug for convenient use.
Ammeter
This module was sold on eBay as “DC Step Down Converter 2A Constant Voltage Current w/ Voltmeter Ammeter”. It has adjustable voltage, current and a display that can show input/output voltage and output current. Very nice for prototyping. For some people this can even be an alternative for a proper bench power supply. This module has connectors that are similar to the “Adjustable” module, the method of adjustment is also similar.
Fine
This module by QSKJ was listed as “Fine 6-24V 12V/24V to 5V 3A CAR USB Charger Module DC Buck step down Converter”. It is one of the smallest modules in the test. This is clearly built for integrating into other projects as it features two solder pads for input. The output is a rather nice female USB port. Listing mentions lots of additional features, such as latest USB identification circuit, protection circuits, ultra-low static current (of 0.85mA) and more.
600mA
This module marked “DM01” is 100% designed for integration. Inputs and outputs are through solder pads. Seems like this module also comes in 3.3, 9 and 12 volts editions. It was listed for sale as “600mA DC-DC Step Down Buck Module 6-55V to 5V Fixed Output Voltage Regulator”. It could be the smallest module of the 6, but the lack of a USB port makes it an unfair comparison. One feature that differentiates this module from others in the test is that it has an “EN” pad. You can control this connector to shutdown and start the module when needed. Shutdown current is advertised as less than 1uA. If you are just going to bridge this pad to “Vin+”, no worries too, this module’s “no load current” is just 0.7mA.
Precise
This module has the same connections as “Fine” but it is a bit larger. It was sold as “3A DC-DC 9V/12V/24V to 5V USB Step Down Power Module 2A Precise Vehicle Charger”.
Voltage and current
Here are some electrical properties of the 6 modules. I didn’t have module properties for “Cigar” so the ranges are based on chip specs and could be better than actual module ranges.
Module
Input voltage
Output voltage
Max output current
Peak output current
Cigar
3 – 40V
5.4 – 5.5V
1.5A
?
Adjustable
4.75 – 24V
0.93 – 18V
2.5A
5A
Ammeter
4.5 – 24V
0.93 – 20V
2A
?
Fine
6 – 24V
5.1 – 5.2V
2.1A
3A
600mA
6 – 55V
5V
0.6A
1A
Precise
7.5 – 28V
5V
2A
3A
Peak current refers to ability to provide high current for a limited length of time. Max current refers to maximum current the module can provide consistently. Mind that some modules mention that operating at max current might require an additional heat-sink or cooling solution.
Few points worth mentioning: first, the “Cigar”, with its fixed USB output connector is providing voltage that is too high by proper USB standards. It could be due to old age or just bad quality. The difference is about 10% and I would consider it not usable. Second, most modules are capable of input voltages up to about 25 volts, but few can do 40 volts and higher. Kudos for that.
Higher switching frequency will mean less ripple on the output (more accurate voltage/current) but causes more overhead due to switching, which reduces the efficiency a bit.
Some inductor values have a ‘?’ next to them. This means the component was not marked and the value was estimated based on recommendations in the datasheet. Usually a lower frequency will require, a larger, higher value inductor.
Testing
First I measured the current used by my device, on the output side of the converter, which was around 50mA. I then I created a dummy load of 100 ohm using two 200 ohm resistors in parallel. I used a resistor array to reduce the load on each individual resistor which was rated for 0.25W. Due to Ohm’s law, a 100 ohm resistor would cause a 50mA load for a voltage of 5 volts, similar to what the device would.
Next I measured the current used by the converter on the input side, for both a device load and a dummy load. I observed that a real load and a dummy load with same average current both have a similar efficiency. A difference could arise since the dummy load power draw is fixed while the device could draw power in bursts, but this didn’t affect the results significantly. I concluded that using dummy resistors is good enough approximation for this test.
I then made dummy loads for 25mA, 50mA and 100mA currents using 1, 2 and 4 resistors in parallel.
To affect the measurement as little as possible, I used the ammeter on the input side (in series) and calculated the current on the output side using Ohm’s law I=V/R. This way there was no impact on the output side which could add a voltage drop and influence the results. Voltage V was measured in parallel and resistance R is known and depends on the dummy load used for each test.
The power supply for the test was providing 12V, but due to the voltage drop in the ammeter, the input voltage of the modules is a bit lower.
Results
I calculated the efficiency of each module per each type of load as:
eff = Pin/Pout = (Vin*Iin)/(Vout*Iout)
Datasheets of some of the chips used in the modules contained an efficiency graph. The efficiency is a function of voltage and current. When available, I added the listed chip efficiency for the relevant Vin and Iout in the last column. Some modules have efficiency charts that don’t cover low current ranges, which might be an indication for the type of load the chips were (not) designed for.
Output current of 25mA
Module
In V
Out V
In mA
Efficiency
Chip efficiency
Cigar
11.82
5.46
21
60%
Adjustable
11.63
5.08
35.65
31%
Ammeter
11.58
5.04
40.04
27%
Fine
11.91
5.12
13.7
80%
87%
600mA
11.9
5.04
14.2
75%
74%
Precise
11.9
4.98
14.75
71%
75%
Output current of 50mA
Module
In V
Out V
In mA
Efficiency
Chip efficiency
Cigar
11.52
5.49
38.6
68%
Adjustable
11.45
5.08
47.44
48%
Ammeter
11.39
5.05
52.2
43%
Fine
11.73
5.13
26.98
83%
89%
600mA
11.72
5.01
26.66
80%
86%
Precise
11.72
4.98
27.3
78%
77.5%
Output current of 100mA
Module
In V
Out V
In mA
Efficiency
Chip efficiency
Cigar
11.15
5.54
76.3
72%
Adjustable
11.22
5.08
79.8
58%
Ammeter
11.18
5.04
76.1
60%
Fine
11.41
5.12
54.6
84%
91%
600mA
11.46
4.9
51
82%
88%
Precise
11.38
4.96
53.5
81%
82%
Conclusion
Differences can be significant as seen above. At the lowest load test (25mA), the worst performer uses 3 times more power than the best.
Efficiency differences between modules become more subtle as load increases: 2x for 50mA and 1.5x for 100mA.
Input voltages are different. Higher current on the input side means higher voltage drop in the ammeter, resulting in a lower input voltage relative to the output of the power supply.
Listed chip efficiency is within 5-10% of the measured module efficiency. The delta could be due to inefficiencies in the module itself or due to differences in the overall conditions (temperature, etc).
And the winner is: “Fine”! This module is clearly the best for low power scenarios. When reaching currents of 100mA the differences between the 3 leading modules are minimal.
What makes “Fine” better than others? It is a relatively new IC. The datasheet is from 2014 where, for comparison, the MP2307’s is from 2008. It also features a very low Rds(on) values (90mΩ/40mΩ), but most interestingly the MP2315 has AAM (Advanced Asynchronous Modulation) power-save mode for light load.
Advanced Asynchronous Modulation (AAM) is a proprietary technology of MPS. With this technology in place, the IC will reduce its frequency when it detects low loads, thus reducing the overhead of switching but potentially introducing instability and ripples. A resistor’s value on the AAM pin determines when to start this behavior. Feel free to correct me in the comments if I am not explaining this correctly.
In conclusion, if you want an efficient module for light loads, you might want to try this one by QSKJ with an MPS MP2315 chip marked as AGCx (I have seen AGCG or AGCE used specifically). If you have other recommendations, please share them in the comments below. Have a great project!
Go to Board Manager under Tools -> Board. Find Stm32F1 and install it.
In the Board list, select Generic STM32F103C Series. Change the upload method to Serial. Choose the correct port number.
Open the blinky example and change it to
/*
BlinkTurns an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your Arduino
model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products
modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(PC13, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(PC13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait for a second
digitalWrite(PC13, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait for a second
}
You often say that, my computer failed to do an specific action or I didn’t broke my PC, my Windows is slow or is running extremely slow, my computer is virus infected, my computer has no sound or my webcam is not working any more … and so on. Often, the solution of computer problems resumes to Windows reinstall.
All of you should know that this operation is not very pleasant: you have to format your windows drive, reinstall drivers and all the applications and it can also be expensive if you pay some professional support. What if I tell you that for Vaio PC’s this operations is made with some few clicks? No disks, no flash usb memory, no other external devices … just few clicks.
Vaio PC’s has a tool called VAIO Recovery Center. This tool allows you to create backup points and restore your windows, to create hardware diagnostics, or you can have the possibility of reinstall programs or drivers, wipe and erase data, creating recovery disks or erase all data and restore your entire system to factory settings.
In this tutorial, I’ll show you how to restore your Vaio PC to it’s factory settings. In other words how to restore your computer to it’s original settings (in the exact state you bought it).
For that you have to:
1. Back-up all your data. Restoring to factory setting means to erase all data and reinstall Windows, drivers and preinstalled applications. If you have a single drive (C:) you have to backup your data to external drive or disks.
2. Start VAIO Recovery Center. Click on Start button and then click on All Programs. From the program list select “VAIO Recovery Center“.
3. Restore complete system menu. From the left menu of Vaio Recovery Center select “Restore complete system“
4. Start button.
5. Select “Restore C: drive” and hit Next.
6. Read the information on this new window, select “I understand” and hit Start.
7. “Are you sure?” If you made backup for all your data and really want to restore your Vaio as it was when you bought it you have to make sure that have it plugged in to a stable source of energy and press YES.
8. So … next you should sit back and relax. Your computer will start showing the next messages
Shuting Down
Windows is loading files …
Restoring your operating system
Please wait a moment while Windows prepares to start for the first time…
Windows Vista setup: The initial setup may take up to 15 minutes. Do not turn off the computer. Click OK to continue the setup process and wait until the “Set up Windows screen appears”. Select OK
9. Take your time until your system install VAIO software
Finish to restart.
10. That’s all. Now, your VAIO has the original operating system, drivers and software. Now you have to configure your VAIO as you want.
IT行业的程序员都会争论高级语言和低级语言哪个好,Linux和Windows哪个好,而对于机器人工程师来说,从现在到可预见的未来里,C是最好的语言,Linux是最好的操作系统,这都毋庸置疑。甚至对于Linux的发行版该选哪个,我们都是很少有质疑的:Ubuntu(The leading OS for PC, tablet, phone and cloud)。原因是机器人操作系统ROS(ROS.org | Powering the world’s robots)是基于Ubuntu开发的,因此在Ubuntu上运行最稳定。注意Ubuntu出了一个中文版叫做Kylin,个人感觉比较坑,建议大家不要装中文版。Ubuntu 作为一个开源操作系统,总是在快速迭代,2016年8月比较稳定的版本是14.04和16.04,建议同学安装14.04。
另外你可以开始学习Matlab当中的神器Simulink了。在大二这一年的学习中,你可能在不少课程里多多少少用到了Matlab。假设你已经在我的推荐下喜欢上了Python,你可能会觉得Matlab的计算工具没有比Python强多少;假设你自己在别人的推荐下喜欢上了mathematica(Mathematica 到底有多厉害? – Wolfram Mathematica),你可能会觉得和Mathematica这种神一样的语言比起来,Matlab弱爆了。但是要注意的是,Matlab最强大的工具是Simulink,通过它你几乎可以仿真一切的物理系统和控制系统。我建议同学可以通过Simulink实现一个倒立摆,然后理解Matlab的强大之处。对此我强烈推荐一个很好的教材(http://ctms.engin.umich.edu/CTMS/index.php?example=Introduction§ion=SimulinkControl),它详细介绍了一些经典的控制系统如何分析以及用Simulink实现。然后我再强烈推荐一个讲Simulink里面一个更加和物理仿真贴近的工具Simscape(Control of an Inverted Pendulum on a Cart)的文章。阅读并实现了这两篇文章里的内容,同学应该会对倒立摆有了比较深刻的认识。倒立摆是机器人学中一个非常重要的模型,因为火箭、导弹、双足机器人、四足机器人,基本都是倒立摆的变形。你自己实现出来的simulink模型一定要存好,以后可能还会再拿出来仔细看。
另外你还需要在大三的尾巴上选定自己将来的细分研究方向,而且开始往这个方向深挖,也就是我在文章开始提到的感知、认知、行为几个方向。当然同时你也不能放松其他方面的知识,尤其是数学基础。我在大三的暑假专门找数学系的同学给我开了个数学小讲座,学习了一点抽象代数的知识,对我后来学习密码学帮助很大。同时我也读了一些拓扑方面的教材(有一本很神奇的书叫做Topopogy Without Tears ),这样才理解了为什么数学分析要用奇怪的符号去解释一些看起来很浅显的道理。
多自由度的机械臂的难点在于机械臂的运动学正反解、运动学控制和动力学控制,基本是一个建模分析和数值算法实现的问题。如果你所在的学校没有一个财力雄厚的机器人实验室的话,你基本上没有机会接触到多自由度的机械臂。这时候之前学到的Simulink和就要学的Gazebo就派上用场了,你可以用Simscape里面的刚体搭一个多自由度机械臂,然后通过Simulink仿真去学习机械臂的控制;也可以用Gazebo的URDF语言写一个机械臂,然后通过Gazebo和ROS的接口去控制机械臂;也可以用ROS里面的著名工具包MoveIt! Motion Planning Framework,不过MoveIt的问题是,他只能仿真运动学,而不能仿真动力学。工业领域对多自由度的机械臂控制通常用一个叫做D-H表示法的建模工具(Denavit),这个东西我并不太会。我只会向同学们推荐我导师的著作《A mathematical introduction to robotic manipulation》。
有一个非常神奇的事实:《A mathematical introduction to robotic manipulation》这本机械臂控制领域的著名教材的第二章和计算机视觉领域的著名教材《An Invitation to 3-D Vision》的第二章基本是一样的,都在讲旋转表示法。这是因为所有的旋转表示法都可以归纳为一种优雅的李群结构:SO(3)群。而计算机视觉和机械臂控制都涉及到理解刚体的旋转,事实上用计算系统去观测和控制所有的刚体构成的系统,理解旋转都是很关键的问题。旋转表示法应该作为研究生阶段的一个重要学习的知识点。
对于多自由度机械手和机器人的locomotion来说,这里面还有非常多可以探索的研究问题。我前面提过接触力和摩擦力很难仿真,大神告诉我现在没有任何一种工具和理论能把接触力和摩擦力正确仿真出来,因此如何在机器人系统里妥善处理对这些力的控制,就是很难的问题了。现在业界的一个前沿发展方向,也是利用机器学习技术来帮助机器人学会处理这些外力,不过人类目前最优秀的多自由度机器人系统,Berkeley的Brett机器人,叠几块积木就要用十分钟(New ‘deep learning’ technique enables robot mastery of skills via trial and error),显然还有很多提升的空间。这方面的问题同学可以关注知乎大神@戴泓楷@周佳骥。
It is also possible to use Arduino. The platfromio.ini will be
[env:genericSTM32F103R8]
platform = ststm32
board = genericSTM32F103C8
framework = arduino
upload_protocol = stlink
9. Connect the blue pill with stlink
STLink pin BluePill pin
GND (3 or 4) GND
3.3V (7 or 8)3.3
SWDIO (2) DIO
SWCLK(6) DCLK
The mode in which STM32 starts is determined by pins BOOT0 and BOOT1 :
BOOT1
BOOT0
Boot mode
X
0
User Flash memory
0
1
System memory (bootloader)
1
1
Embedded SRAM
To get USB Serial working, I did as described in Hardware installation paragraph here and soldered a 1.5k resistor between 3.3V and PA12, while also desoldering R10 from PCB.
Swift Top 10 Articles For the Past Month (v.Oct 2017)
For the past month, we’ve ranked nearly 1,100 Swift articles to pick the Top 10 stories that can help advance your iOS career (0.9% chance to be picked in the list)
Topics in this list: MVVM, Architecture, iPhone X, Animation, Game, Reusable Framework, Server-side, Auto Layout, Algorithms, Type-Safe File Paths, Card UI
Swift Open Source of the Month is included at the bottom.
Mybridge AI ranks articles based on the quality of content measured by our machine and a variety of human factors including engagement and popularity. This is a competitive list and you’ll find the experience and techniques shared by experienced iOS developers useful.
Breaking a bit of a rule here in order to help out a colleague – committing code without tests. Gasp!!! I have been working on this for a while but got interrupted and have not gone back to make sure all my tests work, but a colleague needs this work, so…here it is.
First things first, Google has really made absolutely no attempt to make Google maps accessible at all and the fact that I can take a weekend, without access to their code and make it basically fully keyboard and screen reader accessible (at least for the basic functionality) speaks to how irrelevant accessibility seems to be to them. Shame on you Googlers!!
Secondly, the Google maps markup is obviously generated because it does not contain a single class. It does not contain a style sheet and all of the styling is inline for all the elements. This makes the code particularly difficult to retro. I basically had to resort to looking for the title attributes on elements to try to figure out what they are. This means that this code is language dependent. I did go to the trouble of making it work for both English and German, and would appreciate any assistance in adding support for other languages. Please use the normal pull request mechanism in the a11yfy repository to contribute.
As you can tell from the above paragraph, the code has been integrated into the a11yfy repo BUT is independent of the rest of the library, so using it is simple. Simply include one JavaScript file into your page…
…and then call the gmaps() jQuery method on the container that contains the Google Map element(s)…
jQuery(document).gmaps();
The Accessible Google Maps demo is up on my github.io pages and there is also an example in the google-maps.html file in the examples directory in the repository that you can use to play around with this. Please send feedback via GitHub or comments on this posting.
Limitations of this implementation is that it works only for the default functionality and I have not tested it with multiple maps on the same page (I think it will not work – at least not the sliders and not unless you call the gmaps() function once for each map), but the concept can be expanded to add support for any/all of the Google Maps features. Perhaps you can contribute to this by adding support for the features you are using or requesting a feature on GitHub.
UPDATE 11/24/2013: Added the link to the running example on github.io.
UPDATE 3/23/2014: Fixed the link to the running example on github.io.
The basic zoom and pan controls on embedded Google maps are not keyboard accessible.
This can be addressed by including the map via one of the scripts in the examples below. Try it out by pressing the Tab key to move focus to the map controls. Once a map control has focus it can be activated using the Enter key.
To pan the map, move focus to one of the zoom controls, then press an Arrow key on the keyboard.
Example 1 – default controls
Code
<!DOCTYPE html> <htmllang=“en”> <head> <metacharset=“utf-8”> <title>Keyboard access to Google maps</title> <style>#map_canvas { width:500px; height:400px; } </style> <!–add Google map library–> src=“http://maps.googleapis.com/maps/api/js?sensor=false”><!–add keybpard access script–> (function(){if(!window.visionaustralia) window.visionaustralia ={};
visionaustralia
.addmap =function(domid,lat,lon,zo){
var map; function init(){ var map_canvas = document.getElementById(domid); var map_options ={ center:new google.maps.LatLng(lat,lon), zoom: zo, mapTypeId: google.maps.MapTypeId.ROADMAP } map =new google.maps.Map(map_canvas, map_options);
var hPan =Math.floor(map_canvas.offsetHeight/3); var wPan =Math.floor(map_canvas.offsetWidth/3);
var googListener = google.maps.event.addListener(map,’tilesloaded’,function(){
var titles ={“zoom in”:1,“zoom out”:1,“show street map”:1,“show satellite imagery”:1}; var divs = map_canvas.getElementsByTagName(“div”); for(var i=0,el;el=divs[i];i++){
var title = el.getAttribute(“title”) if(title) title=title.toLowerCase().trim(); if(title in titles){
el
.setAttribute(“tabindex”,“0”); el.setAttribute(“role”,“button”); el.setAttribute(“aria-label”,title); el.addEventListener(“keydown”,function(ev){ var key = ev.keyCode || ev.which; if(key ==13|| key ==32){ var event = document.createEvent(‘HTMLEvents’); event.initEvent(‘click’,true,false); this.dispatchEvent(event);
<p>…. other content</p> //”map_canvas” is the id of the div that will contain the map and the 3 parameters after are: latitude, longitude and zoom level
visionaustralia.addmap(“map_canvas”,45.6,4.9,8); </body> </html>
Example 2 – custom controls
This example replaces the default controls with a custom SVG control.
Press the Tab key to move focus to a control, then press the Enter key to activate it.
To pan the map, move focus to one of the zoom controls, then press an Arrow key on the keyboard.
Code
<!DOCTYPE html> <htmllang=“en”> <head> <metacharset=“utf-8”> <title>Keyboard access to Google maps – custom controls</title> <style>#map_canvas_2 { width:500px; height:400px; } </style> <!–add Google map library–> src=“http://maps.googleapis.com/maps/api/js?sensor=false”><!–add keybpard access script–> (function(){if(!window.visionaustralia) window.visionaustralia ={};
visionaustralia
.addmapII =function(domid,lat,lon,zo){
var map; function init(){ var map_canvas = document.getElementById(domid); var map_options ={ center:new google.maps.LatLng(lat,lon), zoom: zo, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDefaultUI:true } map =new google.maps.Map(map_canvas, map_options);
var hPan =Math.floor(map_canvas.offsetHeight/3); var wPan =Math.floor(map_canvas.offsetWidth/3); var div = document.createElement(“div”); div.setAttribute(“style”,“position:absolute;border:none;outline:none;padding:0px;margin:0px 6px 0px 0px;”); div.innerHTML =”; var yin = div.getElementsByClassName(“yin”)[0]; var yang = div.getElementsByClassName(“yang”)[0]; var bStyl =“position: absolute !important;clip: rect(1px, 1px, 1px, 1px);padding: 0 !important;border: 0 !important;height: 1px !important;width: 1px !important;overflow: hidden”; var yinB = document.createElement(“button”); yinB.setAttribute(“aria-label”,“Zoom out”); yinB.setAttribute(“style”,bStyl); var yangB = document.createElement(“button”); yangB.setAttribute(“aria-label”,“Zoom in”); yangB.setAttribute(“style”,bStyl); div.appendChild(yinB); div.appendChild(yangB); map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(div);
<p>…. other content</p> //”map_canvas” is the id of the div that will contain the map and the 3 parameters after are: latitude, longitude and zoom level
visionaustralia.addmapII(“map_canvas_2”,55.651,12.081,13); </body> </html>
Terms of Use
Developed by Pierre Frederiksen. Pierre is a Digital Access Specialist at Vision Australia
This software is being provided “as is”, without any express or implied warranty. In particular, Vision Australia does not make any representation or warranty of any kind concerning the reliability, quality, or merchantability of this software or its fitness for any particular purpose. additionally, Vision Australia does not guarantee that use of this software will ensure the accessibility of your web content or that your web content will comply with any specific web accessibility standard.
Vue.js Top 10 Open Source for the Past Month (v.Feb 2018)
This is a new monthly series
For the past month, we ranked nearly 150 Vue.js Open Source Projects to pick the Top 10.
We compared projects with new or major release during this period. Mybridge AI ranks projects based on a variety of factors to measure its quality for professionals.
Average number of Github stars in this edition: 1,883
“Watch” Vue.js Top 10 Open Source on Github and get email once a month.
Portal-vue: A Portal Component for Vuejs, for rendering DOM outside of a component, anywhere in the document. [706 stars on Github]. Courtesy of Thorsten Lünborg
Chatire: :speech_balloon: Real time Chat application built with Vue, Django, RabbitMQ and uWSGI WebSockets. [84 stars on Github]. Courtesy of Osaetin Daniel
在互联网这样参与者之间可能互不信任的环境中,怎样才能如何建立一个总账本?让我们从简单的部分开始:数据结构的选择。这个数据结构必须满足一定的属性要求——总账本应该是不可变的。更准确地说,只能增加:可以添加新的交易,但不能删除、修改或对已有交易重新排序。除此之外,还需要一种方法来获得总账本状态的密码摘要。摘要是一个简短的字符串,可以避免存储整个总账本。如果总账本被篡改,所产生的摘要必然会发生变化,从而可以检测到篡改。需要这些属性的原因是:与存储在单个机器上的常规数据结构不同,总账本是由相互不信任的一组参与者共同维护的全局数据结构。这与去中心化数字总账本(decentralizing digital ledgers, 文献7,13,21)的方法是不同的,在分布式数字总账本中,参与者维护本地总账本,并且由用户查询这些总账本来解决冲突。
Stuart Haber和Scott Stornetta方案的简化版本中,文档被不断创建和广播。每个文档的创建者声明一个创建时间(并签名文档)、文档的时间戳和前一个广播文档。前一个广播文档已经签署了自己的前任,所以文档形成了一个很长的倒退链。外部用户不能改变时间戳的信息,因为它由创建者签名;创建者也不能在不改变整个跟随信息链的情况下改变时间戳的信息。因此,如果通过可信来源(例如,另一个用户或专门的时间戳服务)获得链中的单个项目,那么该时刻之前的整个链是锁定的,不可变,并且在时间上有序。进一步,如果你认为系统拒绝错误创建时间的文档,则可以合理地保证文档至少与其声明一样久远。Further, if you assume that the system rejects documents with incorrect creation times, you can be reasonably assured that documents are at least as old as they claim to be.无论如何,比特币只是借用Stuart Haber和Scott Stornetta工作的数据结构,然后重新设计了安全属性(通过增加工作量证明,本文稍后介绍)。
*译注:进一步,如果你认为系统拒绝错误创建时间的文档,则可以合理地保证文档至少与其声明一样久远。原文:Further, if you assume that the system rejects documents with incorrect creation times, you can be reasonably assured that documents are at least as old as they claim to be.
在Stuart Haber和Scott Stornetta的后续文献中,他们介绍了使这个数据结构更加有效和高效的其他方案(其中一些在第一篇论文中有暗示)。首先,可以使用哈希而不是签名来创建文档之间的链接;因为哈希更简单,计算速度更快。这样的链接被称为哈希指针。其次,不是单独对文档进行线程化处理(如果几乎同时创建多个文档,效率可能会很低),它们可以分为批处理组或区块,每个区块中的文档具有基本相同的时间戳。第三,在每个区块内,文档可以用一个哈希指针的二叉树连接在一起,称为Merkle树,而不是一个线性链。顺便提一下,在Stuart Haber和Scott Stornetta的第一篇论文发表的6年之后,即1991年,Josh Benaloh和Michael de Mare独立地提出了这三个方案。
1.2 梅克尔树(Merkle trees)
比特币本质上使用Josh Benaloh和Michael de Mare在1991年和1997年提出的数据结构(中本聪大概不了解Josh Benaloh和Michael de Mare的工作),图2以简化的形式表示。当然,在比特币中,交易取代了文档。在每个块的Merkle树中,叶节点是交易,每个内部节点由两个指针组成。这个数据结构有两个重要的属性。首先,最新块的哈希作为摘要。对任何交易(叶节点)的更改都需要将更改一直传播到块根,以及所有后续块的根。因此,如果你知道最新的哈希值,你可以从不受信任的来源下载余下的总账本,并验证是否改变。类似的观点建立了数据结构的第二个重要属性 ——也就是说,某人可以简单有效地向你证明某个特定的交易包含在总账本中。这个用户只须向你发送该交易块中的少量节点(这是Merkle树的特点),以及每个后续块的少量信息。高效地证明事务的包含能力对于性能和可伸缩性是非常需要的。
John Douceur在他关于Sybil攻击的论文中提出,所有参与BFT协议的节点都需要解决hashcash难题。如果一个节点伪装成N个身份,将无法及时解决N个难题,其伪造的身份将被清除。然而,恶意节点仍然可以获得比只声称单一身份的诚实节点有更多的优势。2005年发布的后续文章(文献1)中提出,诚实的节点应该反过来模仿恶意节点的行为,并声称其计算能力能够承担的尽可能多的虚拟身份。利用这些虚拟身份执行BFT协议,原来的假设“最多只有部分f节点故障”可以用“由故障节点控制的总计算能力的分数至多为f ”来代替。因此,不再需要验证身份,并且开放的对等网络可以运行BFT协议,比特币恰好使用了这个想法,但中本聪提出了一个进一步的问题:什么激励节点执行昂贵的工作量证明计算呢?答案需要进一步的飞跃:数字货币(digital currency)。
2.3 工作量证明和数字现金:双环困境(Proof of work and digital cash: A catch-22)
与当今大多数其他支付系统截然不同,这些想法相当“古老”,可以追溯到数字现金(digital cash)之父David Chaum。实际上,David Chaum也对匿名网络做了开创性的贡献,正是在这个背景下,他发明了这个“数字化名”( Digital Pseudonyms)这个创意。在他1981年的论文“Untraceable Electronic Mail, Return Addresses, and Digital Pseudonyms(文献9)” 他说:“数字化名”是一个公钥,用来验证由相应私钥的匿名持有者是否取得签名。
相反,学术界却难以推销其发明。例如,不幸的是,最初的工作量证明研究人员没有得到比特币的信贷(credit for bitcoin),可能是因为这项工作在学术界以外并不为人所知。在学术界,诸如发布代码和与从业者合作等活动没有得到充分的奖励。事实上,迄今为止,学术工作量证明的原始分支仍然不承认比特币的存在!与现实世界接触不仅有助于获得信贷(credit),而且还会减少轮子再造,并且是找到新创意。
6 致谢(Acknowledgements)
The authors are grateful to Adam Back, Andrew Miller, Edward Felten, Harry Kalodner, Ian Goldberg, Ian Grigg, Joseph Bonneau, Malte Möser, Mike Just, Neha Narula, Steven Goldfeder, and Stuart Haber for valuable feedback on a draft.
8. Castro, M., Liskov, B. 1999. Practical Byzantine fault tolerance. Proceedings of the Third Symposium on Operating Systems Design and Implementation; http://pmg.csail.mit.edu/papers/osdi99.pdf.
9. Chaum, D. 1981. Untraceable electronic mail, return addresses, and digital pseudonyms. Communications of the ACM 24(2): 84-90; https://dl.acm.org/citation.cfm?id=358563.
10. Chaum, D. 1983. Blind signatures for untraceable payments. Advances in Cryptology: 199-203.
11. Chaum, D. 1985. Security without identification: transaction systems to make Big Brother obsolete. Communications of the ACM 28(10): 1030-1044; https://dl.acm.org/citation.cfm?id=4373.
19. Garay, J. A., et al. 2015. The bitcoin backbone protocol: analysis and applications. Advances in Cryptology: 281-310; https://eprint.iacr.org/2014/765.pdf.
23. Haber, S., Stornetta, W. S. 1997. Secure names for bit-strings. In Proceedings of the 4th ACM Conference on Computer and Communications Security: 28-35; http://dl.acm.org/citation.cfm?id=266430.
27. Lamport, L., et al. 1982. The Byzantine Generals Problem. ACM Transactions on Programming Languages and Systems 4(3): 382-401; https://dl.acm.org/citation.cfm?id=357176 .
31. Levy, K. E. C. 2017. Book-smart, not street-smart: blockchain-based smart contracts and the social workings of law. Engaging Science, Technology, and Society 3: 1-15; http://estsjournal.org/article/view/107.
36. Narayanan, A., et al. 2016. Bitcoin and Cryptocurrency Technologies: A Comprehensive Introduction. Princeton University Press; http://bitcoinbook.cs.princeton.edu/.
38. Pinkas, B., Sander, T. 2002. Securing passwords against dictionary attacks. Proceedings of the Ninth ACM Conference on Computer and Communications Security: 161-170; https://dl.acm.org/citation.cfm?id=586133.
Ethereum on Raspberry Pi: secure wallet and complete node with redundant storage
Sep 6, 2017 13 minute read
In this post, I’m going to show you how to build a complete ethereum node and wallet using a raspberry pi 3. Why? Because running an ethereum node allows us to: contribute to the Ethereum network; store our wallets in a private and secure location; and it can be useful also when experimenting some kind of crypto-algorithmic trading (you can generate a new address from code, being sure that’s synced and stored in a private location, do transactions and so on).
First of all, the requirements list (with Amazon’s links!):
The Raspberry Pi 3 is the most supported ARM device around. It has 1 GB RAM, 4 USB 2.0 ports, and 1 ethernet port. It’s possible to run Linux on it; in fact there are a lot of distributions available.
Keeping the Raspberry Pi powered on 24/7 produces heat: we have to dissipate it. This guarantees a long life to our device, plus in the kit we also find a nice plexiglass case that allows us to protect the device from external damaging.
A power outage is the second main cause of hardware failure after heating (or better, of filesystem corruption and subsequent data loss). To prevent serious damage a UPS is required. Also, the Raspberry Pi power consumption is not that high, therefore a UPS can keep it up for a reasonable amount of time (hey reader, are you a Raspberry Pi hacker and you know how to use the GPIOs to monitor the wall outlet and trigger a safe shutdown procedure when the UPS is UP but the wall power is DOWN? Maybe you also know how to start it when to power comes back, and doing all this without any information from the UPS (no USB available)? Contact me!).
The blockchain size increases in size day by day. A simple SD card is not enough to store the whole blockchain. Moreover, the SD card is a single point of failure and we should prevent that a failure makes us lose the blockchain and – most importantly – the wallet!
The Raspberry Pi does not provide enough power to the USB ports. Thus, since almost every external HDD is not externally powered, we have to provide enough power using a USB switch.
The Raspberry Pi comes with no storage, an SD card is required to install an operating system.
OK, let’s start!
Archlinux ARM
I choose this one instead of the most common Raspbian because I love Archlinux. Also, it’s really easy to install and use. More importantly, geth (the command line interface for running a full ethereum node) is already packaged and available in the community repository, therefore installing it is as easy as pacman -Syu geth.
Installing Archlinux ARM is straightforward. The installation guide on how to create the SD card is pretty clear. I’m going to show 2 ways to create the SD card. The first on Linux, the second on Windows.
Prepare the SD card while running Linux
Insert the SD card into your SD card reader. The device /dev/mmcblk0 appears.
# Become root:
su
# Create a new partition table
fdisk /dev/mmcblk0
# From the guide:# At the fdisk prompt, delete old partitions and create a new one:# Type o. This will clear out any partitions on the drive.# Type p to list partitions. There should be no partitions left.# Type n, then p for primary, 1 for the first partition on the drive, press ENTER to accept the default first sector, then type +100M for the last sector.# Type t, then c to set the first partition to type W95 FAT32 (LBA).# Type n, then p for primary, 2 for the second partition on the drive, and then press ENTER twice to accept the default first and last sector.# Write the partition table and exit by typing w.# Create a new work directory and move in
mkdir /tmp/wd
cd /tmp/wd
# Create and mount on /boot the FAT filesystem
mkfs.vfat /dev/mmcblk0p1
mkdir boot
mount /dev/mmcblk0p1 boot
# Create and mount on / the ext4 filesystem
mkfs.ext4 /dev/mmcblk0p2
mkdir root
mount /dev//mmcblk0p2 root
# Download and extract the root filesystem
wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-2-latest.tar.gz
bsdtar -xpf ArchLinuxARM-rpi-2-latest.tar.gz -C root
sync
# Move boot files to the first partition:
mv root/boot/* boot
# Umount the two partitions
umount boot root
Now you can insert the SD card into the Raspberry Pi. Connect the UPS to the wall outlet, the Raspberry and the USB switch to the UPS, the HDDs to the switch and the switch to the Raspberry. Connect the ethernet cable too and power it on. Done! You can jump to the Archlinux configuration.
Run Win32 Disk Imager. Select the right device, the .img file downloaded and Write.
Your SD card is almost ready. Almost, because we have to resize the filesystem of the root partition, otherwise we only have 2GB available instead of the 32 GB that our SD card allows. Now you can insert the SD card into the Raspberry Pi. Connect the UPS to the wall outlet, the Raspberry and the USB switch to the UPS, the HDDs to the switch and the switch to the Raspberry. Connect the ethernet cable too and power it on.
Download putty and connect to the IP that the router assigned to the Raspberry Pi. Username alarm, password alarm.
Now we have to resize the filesystem of the root partition, while the system is running. To do that we have to delete the partition (don’t worry, data will be preserved) and create a new one that occupies all the free space.
# Become root
su # password root# Use fdisk to change the partition table
fdisk /dev/mmcblk0
# At the fdisk prompt, delete the partition number 2# Type d then 2. # Create a new primary partition (id 2)# Type n then p. # At the prompt for the first sector and last sector just press enter.# This will automatically start from the old first sector and will set the last# sector to the end of the available space.# Write the partition table and exit by typing w.# Now reboot
reboot
Now log in again to the Raspberry Pi.
# become root
su # password root# Now we use resize2fs to let the kernel aware that the filesystem has been enlarged
resize2fs /dev/mmcblk0p2
# logoutexit
Done. Now you’re ready to configure your brand new Archlinux setup.
Archlinux Configuration
Our aim is to setup a full ethereum node, whose data (blockchain and wallet) is stored onto the external hard drives. Before doing that we have to configure a RAID 1 for our external HDDs.
Note: the Archlinux image contains out-of-date software. This is never a good thing. Updated software give us better security. However, we’re going to exploit this fact before upgrading the system.
The ssh server installed is so old that still allows, as a default option, the remote login of the root user. We’re going to exploit this in order to create and mount the RAID 1 partition on /home. In this way, we can completely remove the home directory of the alarm user (and of any other user with a home directory) without any inconvenient.
Login remotely as root user (under windows use Putty with user root and password root, under Linux just user ssh with the same credentials)
RAID setup
Our 2 external HDDs are located under /dev/sda and /dev/sdb. First of all, we’re going to create a partition table on those devices and a partition for our data.
Since we’re going to store a lot of data on these hard drives it’s recommended to create a GPT partition table. For doing that, we need gptfdisk.
# Install gdisk
pacman -Sy gptfdisk
# Use it to partition both hard drives. Default values are OK since# we want to create a single partition as big as the whole hard drives
gdisk /dev/sda
# Now create a single partition as big as the drive# Type n then p.# Accepts the defaults for every following question.# Type w to write and exit
gdisk /dev/sdb
# Do the same exact procedure of above# We created /dev/sda1 and /dev/sdb1 partitions# Create an ext4 filesystem on these partitions
mkfs.ext4 /dev/sda1
mkfs.ext4 /dev/sdb1
Alright, we partitioned our HDDs. Now we can create a logical RAID 1 volume. RAID 1 is the most straightforward RAID level: straight mirroring. This means that if one of our drives fails, the block device provided by the RAID array will continue to function as normal. We’re now going to use mdadm to create the new block device /dev/md0:
Since we’re still logged as root, we can remove the current default user alarm and its home directory. Then we’re going to mount our RAID device to /home in order to have redundancy for our data. Next, we create a new user to use geth with.
userdel -r alarm
mount /dev/md0 /home
# Add the user `geth`. Automatically creates /home/geth
useradd geth
# Set a new passowrd for user geth
passwd geth
Now, we need to make the mount of /dev/md0 on /home permanent across reboots. Change the /etc/fstab adding the line (using nano or vim):
/dev/md0 /home ext4 defaults,nofail 0 0
Save the changes and exit.
Now that we have: a new user geth; set a new password; a RAID device that’s mounted on /home; we’re ready to upgrade the whole system.
# First change the root password
passwd
# Now upgrade everything
pacman -Syu# reboot
reboot
After the upgrade, we’re unable to login via ssh as root (that’s a good thing). Let’s login as geth.
We’re now going to install geth, configure it to start at boot and fix some little problem that using external HDDs can cause to our RAID-1 setup.
geth & startup services
Before installing geth, we have to disable any power saving options in our HDDs. We have already connected the external HDDs to an externally powered USB in order to give them enough power to work. External hard drives slow down when the disk is not used and/or power them off. This can be a problem for our RAID configuration because once a drive turns off, it becomes unavailable as storage and so our RAID setup becomes useless.
We have to disable both HDDs power saving settings and we have to do it every time we turn on our Raspberry Pi. A simple systemd service file is what we need.
su # become root# install hdparm
pacman -S hdparm
Now, as root, use your preferred text editor and create the file /etc/systemd/system/hdparm.service with this content:
Please note that we’re setting up a light node. This means that you won’t download the whole blockchain. This is the only mode that requires low hardware resources and that can work on a Raspberry Pi right now.
You can change the maxpeers flag with the number of peers you desire. The highest your internet speed is, the highest can this number be (the default value is 25).
Let’s enable this process on boot and make it run from the geth user.
systemctl enable geth@geth.service
systemctl start geth@geth.service
# back to geth userexit
You can monitor the output of geth with systemctl status geth@geth.service and you can launch a console attached to the running node with geth attach (from the geth user).
A small note:
The blockchain synchronization can take a very long time. Also, geth uses a lot of RAM when syncing. Therefore is not unusual that the kernel kills the process and then systemd restart it. However, once the whole blockchain has been synchronized and the number of blocks to receive in an hour is low, a Raspberry Pi with 1 GB of RAM can handle the synchronization without crashing.
Ideally, if you already have a geth node synchronized, it’s suggested to copy the blockchain using scp or any other remote copy tools instead of using geth.
Conclusion
In this post, I described how to set up an Ethereum node on a Raspberry Pi 3 using Archlinux ARM. After the initial sync, we can use it to send/receive ETH, handle power failures thanks to the UPS and have redundant data to handle HDDs failures.
Please note that there are a lot of things to do to increase the security of your node. I just leave here few hints:
Do not expose the node outside the LAN
iptables with ‘deny all’ policy is a good friend
Configure your firewall in the router
Use strong passwords
Do not install sudo. If you install it, please add Defaults rootpw and use a different password for geth and root.
Place the node in a secure location
Evaluate if encryption of the RAID device is an option (although geth force us to protect our wallets with a passphrase, that’s enough for my needs).
If you found this post helpful let me know it! Just leave a comment in the form below.
And since we are here to try ETH, if you want to offer me a beer (or anything else) you can just send me ETH to: 0xa1d283e77f8308559f62909526ccb2d9444d96fc.