Quantcast
Channel: Davide Gironi blog
Viewing all 196 articles
Browse latest View live

vSphere ESXi backup strategies for lowering power consumption

$
0
0
For my home development servers I use the vSphere ESXi 6.5 hypervisor.


At home I do not need all the virtual machines on that server to be online 24/24 365/365, so this server is not always powered on. I need strategies to power up this server on needs.
That was achived by using the Wake on LAN (WoL).
I enable WOL on BIOS of that PC, so I can start the server whenever I need using the poweroff.exe utility (http://users.telenet.be/jbosman/applications.html) and a small batch file that simply launch poweroff.
Let's suppose my server has the IP 192.168.1.10 and mac 010203040506 the command below should start the server:
poweroff.exe wol -ip 192.168.1.10 -subnet 255.255.255.0 -mac 010203040506

Then I need something to backup virtual machines on that hypervisor, I build a bounch of script to perform the backup strategy I need.

But at first, let's talk about the hypervisor and the hardware used.
I was using ESXi since 5.0, this year I switch from 5.5 to 6.5.
My main server it's a HP Compaq dx2400 microtower powered by a Xeon E5440 and 8Gb RAM, the hypervisor is intalled on a 32Gb USB flash drive and hosts on a 1Tb HDD. It uses almost 60W.
This PC comes out with a Core 2 Due processor, but I've upgraded it to a Xeon E5440, due to the simplicity of the operation. A note about this upgrade, the Xeon processor I've used comes from a chinese seller already modded for the LGA 775 socket, also the latest BIOS for the motherboard of this PC (5.37 Rev.) does support the Xeon E5440.
I just need to install the new Xeon CPU, reset the BIOS, and power it up. Then I've enabled VT on bios.
For further information on this mod, search for LGA 771 to 775 adapter mod. To be sure my motherboard supports this CPU I've used the intelmicrocodelist.exe tool to look at the CPU supported by my motherboard BIOS.

I would like to backup each virtual machine on a remote disk. I've done this mounting a NFS disk on the ESXi.
The NFS service and disk is provided by a Netgear Stora NAS.
On that NAS i enabled NFS by kernel mode, If you've fot a Netgear Stora you can find further information here: http://www.openstora.com/wiki/index.php?title=Kernel_mode_NFS.
I use a Samba shared folder as main NFS entry point, in order to simply the backups download and look at all the files. My NFS entry in /etc/exports map the NFS user to the main stora user, that way by the share I can eventually delete files. On NFS this is authorized by the all_squash option. Let's suppose my store username is yourusername, the NFS folder is /home/yourusername/folder and yourusername id and group id are 10 and 11 (use the folling commands to get a username and group id on linux $id -u yourusername and $id -g yourusername).
My /etc/export entry looks like this:
/home/yourusername/folder 192.168.1.0/255.255.255.0(rw,sync,all_squash,anonuid=10,anongid=11,no_subtree_check)
As a side note, that Netgear Stora NAS is also modded to mount two disk wihout raid. I use one of the disk for PCs backup and the other one for ESXi backups.

Now, let's came to the backups.
I've chosen ghettoVCB script (https://github.com/lamw/ghettoVCB) as my backup engine because it's simple, opensource, and well documented.
ghettoVBS is is installed using instructions from the ghettoVCB page. This are the basic steps:
Download the ghettoVCB offline bundle to tmp folder and run
$esxcli software vib install -d /vghetto-ghettoVCB-offline-bundle.zip -f
Mount a NFS datastore on the hypervisor (ex backups01)
Make a ghettoVCB folder in the backup datastore (or other one)
$mkdir /vmfs/volumes/backups01/ghettovcb
Copy ghettoVCB.conf to the folder created
$cp /etc/ghettovcb/ghettoVCB.conf /vmfs/volumes/backups01/ghettovcb/ghettoVCB.conf
Edit ghettoVCB.conf at least set the backup folder
  VM_BACKUP_VOLUME=/vmfs/volumes/backups01
and the backup rotation count
  VM_BACKUP_ROTATION_COUNT=2

The backup strategy I've implemented is simple.
I run ghettoVCB each week to perform a full backup of each virtual machine, ghettoVCB handles the backups rotation. In order to lowering power consumption (remember that this server is not always on) I've implement this simple strategy, running a script at the the boot stage the hypervisor, This script:
  1. adds ghettoVCB crontab for day N of week time HH:MM+20min
  2. check if the hypervistor is switched on "next to" day N of week time HH:MM, if so
  • add a shutdown trigger file (the shutdown operation only runs if exists a shutdown trigger file)
  • add crontab for shutdown the server after H hours
An external device sends a WOL packet at day N of week time HH:MM-10min, if the hypervisor it is switched on at that time nothing happens, if not it will power up, schedule the ghettoVCB backup and eventually power down after the backups end.
The shutdown trigger file it is usefull to interrupt the shutdown procedure. Imagine that one want the server to stay on, he just has to delete the shutdown trigger file, available on the NFS Samba shared folder of backups.
This is all packed in the backuphelper.sh file you can find here https://gist.github.com/davidegironi/73f7dc8c65625d51b9a45e9fbe2f73c2
To use the backuphelper, you have to make a backuphelper folded
$mkdir /vmfs/volumes/backups01/backuphelper
Copy backuphelper.sh and esxidown.sh to the folder created
$cp /tmp/backuphelper.sh /vmfs/volumes/backups01/backuphelper/backuphelper.sh
$cp /tmp/esxidown.sh /vmfs/volumes/backups01/backuphelper/esxidown.sh
Edit backuphelper.sh setting the running parameters at top of file
Run backuphelper.sh at startup, edit file /etc/rc.local.d/local.sh adding commands below
  /vmfs/volumes/backups01/backuphelper/backuphelper.sh S

This backuphelper uses the esxidown script (https://github.com/sixdimensionalarray/esxidown) to gently shutdown the hypervisor.

The external device I'm using to send the WOL packet is a D-Link DSL-2750B/DSL-2751 rev D1 with OpenWrt installed, which I'm using as the main DHCP/DNS server in my home network. On this OpenWrt the etherwake package is installed, the etherwake command for WOL is set as a Scheduled Task.
Let's suppose my server mac is 010203040506 and I want to switch the server on on day 6 at 2:10 using the eth0.1 port, the command will look like this:
10 2 * * 6 /usr/bin/etherwake -D -i "eth0.1""01:02:03:04:05:06"
Also, if you would like to make a backup, let's say the first saturday of month, the crontab schedule will look like:
10 2 1-7 *   *  [ "$(date '+%a')" = "Sat" ] && /usr/bin/etherwake -D -i "eth0.1""01:02:03:04:05:06"

Another thing to take in consideration is the timezone, and time accuracy, all my devices have the NTP client enabled, and all the timezone are UTC.


Notes
  • read risk disclaimer
  • excuse my bad english

MQ gas sensor correlation function against temperature and humidity

$
0
0
We have taken a look at the MQ sersor in this post here:
As I said those sensor are electro-chemical. Accuracy of those sensor is not the best. Also they will react to many gases. It means that if you are trying to measure the ppm of a certain gas with this sensor, you will have false measurement values if any of the other gas that the sensor react to, changes.
Here I will "overengeneer" on this type of sensor, trying to correlate the MQ sensor readings to temperature and humidity too, even if this correlation to me is not prominent. The correlation formula I've found may be wrong, so let me know if there is something to fix here.

As the previous post, let's consider the MQ-135 sensor as reference, find below the "sensitivity characteristics of the MQ-135" figure of the datasheet we used to obtain ppm from resistance redings.


The MQ sensor datasheet also comes with a "typical dependence curve of the sensor on temperature and humidity" let's call it dependance curve.


It shows us how the Rs/Ro change against temperature and humidity.

What we are searching here, it's a way to relate the sensitivity characteristics curve with the temperature and humidity dependance curve.
It means, a way to find out ppm, reading the sensor resistance at any given temperature and humidity. 

Before going ahead.
Notice that the sensitivity characteristics curve, from which we have found the correlation function ppm=a*(Rs/Ro)^b coefficients a and b, it's acquired under certain circumstances, as example for the MQ-135 sensor 20C temperature, 65% humidity, O2 21%, Rl 20k, Ro at 100ppm of NH3 in the clean air.

The dependance curve of the sensor also it's acquired under certain circumstances, as example for the MQ-135 sensor Rs at 100ppm of NH3, Ro at 100ppm of NH3 in air at 33%RH and 20C.

At first we have to ask if we can relate sensitivity characteristics curve to dependance curve of the sensor?
Each curve it's taken under different circumstances, the first has both Rs and Ro acquired at 20C temperature, 65% humidity, the second one has Ro acquired at 20C temperature, 33% humidity. Both ratio related to a Ro at 100ppm of NH3.
The Ro of the sensitivity characteristics curve it's taken at Ro at 100ppm of NH3 in clean air, just as the Ro of the dependance curve, only temperature and humidity differs. Obviously it means that the sensor resistance at 100ppm of NH3 Rs it's just Ro, at any temperature and humidity,
This does not means that the sensitivity characteristics curve it's valid under any temperature and humidity, notice that the dependance curve may differs under different gas concentration, or different gas. We just know it's acquired for 100ppm of NH3, but we do not know what's the dependance curve at other gas concentration. Also the sensitivity characteristics curve may differs under different circumnstances of temperature and humidity.
If we suppose that the dependance curve it's linear over different gases and concentration, we may relate the ratio of the sensitivity characteristics curve to dependance curve.

We get the a and b coefficients for the correlation function ppm=a*(Rs/Ro)^b from the sensitivity characteristics curve.
To estimate the Ro, we read the sensor resistance at temperature T1 and humidity H1 (Rs_T1CH1%) given a know amount of gas to estimate. We are trying to estimate Ro at 100ppm of NH3, at temperature 20C and humidity 65% (Ro_20C65%).
Ro_20C65%=Rs_T1CH1%*(a/ppm)^(1/b)
Because the sensitivity characteristics curve it's acquired 20C and 65%, we need to correlate Rs_T1CH1% to Rs_20C65%. We can do this, because we have assumed that the dependance curve it's linear over different gas amount.
Defined Ro at 100ppm of NH3 20C and 33% as Ro_20C33%, by the dependance curve
Rs_T1CH1% / Ro_20C33% = m
and
Rs_20C65% / Ro_20C33% = n
so
Rs_20C65% = (n / m)*Rs_T1CH1%
and
Ro_20C65%=(n / m)*Rs_T1CH1%*(a/ppm)^(1/b)

Now conditions changed, we are at temperature T2 C and humidity H2 % (Rs_T2CH2%).
So hour function is not yet valid
ppm=a*(Rs_T2CH2%/Rs_20C65%)^b
for this function to be validated, we need the to correlate Rs at temperature T2 C and humidity H2 % (Rs_T2CH2%) to temperature 20C and humidity 65% (Rs_20C65%).
As we does for the previos correlation
Rs_T2CH2% / Ro_20C33% = t
and
Rs_20C65% / Ro_20C33% = q
so
Rs_20C65% = (q / t)*Rs_T1CH1%
and
ppm=a*((q*Rs_T1CH1%)/(t * Rs_20C65%))^b

To find out the correlation factor between this ratio, the simpler thing here, is to build up two lookup tables, one for each of the curves showed.
On the MQ-135 we will get a lookup table for 85%RH and one for 33%TH curve.
We can do this by using a tool like WebPlotDigitalizer.
Now, we have two lookup table, for two different humidity values. Each of the points of that lookup tables represent the Rs/Ro against a certain temperature.

lookup_33 = (t_1C33%, RsRo_1C33%),  (t_2C33%, RsRo_2C33%) ... (t_nC33%, RsRo_nC33%) 
lookup_85 = (t_1C85%, RsRo_1C85%),  (t_2C85%, RsRo_2C85%) ... (t_nC85%, RsRo_nC85%)

We can use linear interpolation (https://en.wikipedia.org/wiki/Linear_interpolation) to relate Rs/Ro to any temperature and humidity.

As example, suppose we have read Rs at 22C, 50%
Rs_22C50%/Ro_20C33% will be the interpolation between Rs_22C33%/Ro_20C33% and Rs_22C85%/Ro_20C33%.
Rs_22C33%/Ro_20C33% = RsRo_20C33% + (22C - 20C)*(RsRo_30C33% - RsRo_20C33%)/(30C-20C)
Rs_22C85%/Ro_20C33% = RsRo_20C85% + (22C - 20C)*(RsRo_30C85% - RsRo_20C85%)/(30C-20C)
Rs_22C50%/Ro_20C33% = RsRo_22C33% + (50% - 33%)*(RsRo_22C85% - RsRo_22C33%)/(85%-33%)

At the end it's just a matter of linear interpolation, to find out m and n values to estimate Ro at 100ppm NH2 temperature 20C and 65% humidity, and t and q values to estimate Rs at temperature 20C and 65% humidity.

All have been implemented and tested using an ATmega8.
The underlying chart shows the CO2 ppm correlation.
Time is reported on the x-axis, CO2 ppm values on the left y-axis, humidiy and temperature values on the right y-axis.
The MQ135 resistance reading are then translated to ppm with and without the temperature / humidity correlation method (green lines).
A reference NDIR sensor shows us an accurate CO2 reading.
As you can see the CO2 temperature/humidity correlation function works slightly better than the uncorrelated one.
Tests are repeated 3 times per sensor, using 3 MQ135 sensors.


The code below implements the resistance to ppm corrleation functions, and also the temperature and humidity correlation functions, as the main correlation function mq_getppmtemphumd.


Code


Notes
  • read risk disclaimer
  • excuse my bad english

MQ gas sensor correlation coefficients

$
0
0
I've have talk about MQ sensors here:
http://davidegironi.blogspot.it/2017/05/mq-gas-sensor-correlation-function.html

In the post linked above I've discuss a method to correlate the sensor resistance to a gas ppm using the datasheet curve named "sensitivity characteristics of the MQ-135" and the formula:
ppm=a*(Rs/Ro)^b.
Someone ask me about sensor and correlation coefficients of various gasses, so here I will post some correlation coefficient for the a few MQ sensor and gasses.

sensorgasabmin Rs/Romax Rs/Ro
MQ2LPG591.283 -2.076502 0.256166 1.68543
MQ3alcohol0.3923202 -1.493249 0.11433752.497754
MQ4CH41041.333 -2.729007 0.43652771.830508
MQ5CH4217.4972-2.422111 0.20587151.035233
MQ6LPG940.2178 -2.521573 0.3915661 1.847477
MQ7H264.86522 -1.405261 0.05323301 1.203488
MQ8H21079.683 -0.6416874 0.03115283 13.84067
MQ135CO2110.3794 -2.721706 0.8038119 2.416431

Those values have been found using the method proposed in the above post, and the figures posted below.
In order to use the correlation function, you now need to compute the Ro value. You can find this value reading the sensor resistance at a know amount of ppm, compy in the gases ppm limits of the datasheet, and then use this formula:
Ro=Rs*(a/ppm)^(1/b).

Those are the
 - collected points: https://bitbucket.org/snippets/davidegironi/z9AMEr/mq-gas-sensor-correlation-coefficients
that has been processes using the following
 - R script: https://gist.github.com/davidegironi/b7be6b7cace6b475dd42c48c3e62fcf4










Notes
  • read risk disclaimer
  • excuse my bad english

OpenWrt Access Point & Routed AP with Guest WiFi on AGPF modem/router

$
0
0
The Pirelli Alice Gate VoIP 2 Plus, also known as agpf, is a ADSL modem router with WiFi and Voip capabilities.
The main chip is the BCM6358KFBG, they support OpenWrt.
OpenWrt is a linux distribution for embedded devices, you can find further information on the openwrt website: https://openwrt.org. Although hardware Voip and ADSL is not supported on this router, this device can be pretty usefull for other network roles.

I've saved three of them from junkyard and I start playing with that devices.

This post reports how I've built a Access Point and a Routed Access Point for a Guest WiFi using OpenWrt.
Also a wired guest connection is served.

Let's suppose we are serving our main network on 192.168.1.0/24 ip ranges, and we would like a guest network, isolated from the 192.168.1.0/24 one, on the 192.168.2.0/24 ip range.


The following steps is needed only if your router hasn't OpenWrt on board.
The first step to start the game will be load the OpenWrt firmware.
The following steps may brick your device, so continue at your risk.
You can find a complete guide here: https://wiki.openwrt.org/toh/pirelli/agpf.
Summarizing it will be very simple, you just have to connect the router to a RS232 port, set the port at 115200 baud, no parity, 8bits and open your terminal software. Here you can the serial connection pins https://wiki.openwrt.org/_media/media/pirelli/alice-agpf.jpg, on the left the GND, top right RX, bottom right TX).
To enter the CFE prompt, you can press any key during the boot process, when the countdown stop message appears.
You have to run a TFTP server, to provide the firmware to your router.
I'm using tftpd32 (http://tftpd32.jounin.net/) and the Chaos Calmer 15.05.1 firmware (https://downloads.openwrt.org/chaos_calmer/15.05.1/brcm63xx/generic/openwrt-15.05.1-brcm63xx-generic-AGV2+W-squashfs-cfe.bin).
Just put the firmware in your tftpd32 folder, run the software and select the server interface to serve.
Supposing your interface is 192.168.1.120, on the CFE prompt you have to run the flashimage command as follow
> flashimage 192.168.1.120:openwrt-15.05.1-brcm63xx-generic-AGV2+W-squashfs-cfe.bin
This would load the firmware on your router.
The router will reboot, and you can now access the router by the 192.168.1.1 address on your web browser.
Note: if you would like to change your IP address using serial interface, just edit the network config file using the command
$vi /etc/config/network
You should change the ipaddr of the interface 'lan', also you can add your gateway and dns option here.


Now that you have a working OpenWrt device, we can setup it to provide the main WiFi access and a guest WiFi access.

Just open the Luci web interface of your OpenWrt, set your password and enable a SSH access to the main lan. The SSH access allows us to run configuration command throgh a SSH terminal.

Before going on we have to say that the WiFi board of this router does not support multiple SSID, so we have to use a USB adapater.
The following steps is needed only if your OpenWrt router does not supports multiple SSID and you have a RT72 driver compatible device, otherwise you must use your device proper driver.
I've a Ralink RT2501USB/RT2571W usb adapater, to make it work with at AGPF router we have to load the modules for USB and for the adapter.
We will do this by the opkg package system.
After the system reboot, to update the packages repository, we will run the command
$opkg update
We will install usbutils and the wireless tools, not closely needed but may be usefull
$opkg install usbutils
$opkg install wireless-tools
Now we are going to install USB modules
$opkg install kmod-usb-uhci
$opkg install kmod-usb2
A reboot is needed now.
We will install the Ralink RT2501USB/RT2571W (RT73) module
$opkg install kmod-rt73-usb
We will now reboot.
Now you should see a secondary WiFi on the Luci web interface.

We can now setup the first WiFi interface, and bind that to the lan network.
The DHCP must be disabled on the lan network to simulate an AP bridge behaviour.

We will make a new switch, that is new VLAN.
On VLAN 1, we disable port 2, 3 and 4, set 5 is untagged
On VLAN 2, we enable port 3, 5 is tagged
We are going to use port 3 as a wired guest port.
Note that the port 5 is the CPU, the physical port for port 3 is Eth4, port 2 Eth3.. and so on.
The untagged traffic will run on VLAN 1, the tagged one on VLAN 2.

Now we have to add guest firewall rules for guest interface.
This rule has to accept input, accept output, reject forward and Allow forward to destination zones -> lan, this way all the traffic will be forwared to lan.

The lan firewall rule must have enabled Masquerading and MSS clamping, it also have to Allow forward from source zones -> guest, to accept the forward traffic from guest, and Restrict Masquerading to all subnet but not the 192.168.1.0/24, by the value !192.168.1.0/24.

We can now add a guest interface, as bridge and add the VLAN 2 created on port 3.
We are going to set the guest interface with a static address, and enable DHCP for the guest interface assign the interface to the guest firewall zone.

Now we can set the guest WiFi, binding it to the guest interface.

Now we would have a primary WiFi over our main subnet 192.168.1.0/24, and a guest WiFi + a guest wired connection through port 3 of the router over our secondary subnet  192.168.2.0/24.

You can find below the main configuration files as example.

/etc/config/network
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config globals 'globals'
option ula_prefix 'fd6e:e9df:eb78::/48'

config interface 'lan'
option ifname 'eth1'
option force_link '1'
option type 'bridge'
option proto 'static'
option ipaddr '192.168.1.3'
option netmask '255.255.255.0'
option ip6assign '60'
option gateway '192.168.1.1'
option dns '192.168.1.1'

config interface 'wan'
option ifname 'eth0'
option proto 'dhcp'

config interface 'wan6'
option ifname 'eth0'
option proto 'dhcpv6'

config switch
option name 'eth1'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'eth1'
option vlan '1'
option ports '0 1 2 5'

config switch_vlan
option device 'eth1'
option vlan '2'
option ports '3 5t'

config interface 'guest'
option type 'bridge'
option proto 'static'
option ifname 'eth1.2'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'

/etc/config/firewall
config defaults
option syn_flood '1'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'

config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
option network 'lan'
option masq '1'
option mtu_fix '1'
list masq_dest '!192.168.1.0/24'

config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
option network 'wan wan6'

config forwarding
option src 'lan'
option dest 'wan'

config rule
option name 'Allow-DHCP-Renew'
option src 'wan'
option proto 'udp'
option dest_port '68'
option target 'ACCEPT'
option family 'ipv4'

config rule
option name 'Allow-Ping'
option src 'wan'
option proto 'icmp'
option icmp_type 'echo-request'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-IGMP'
option src 'wan'
option proto 'igmp'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-DHCPv6'
option src 'wan'
option proto 'udp'
option src_ip 'fe80::/10'
option src_port '547'
option dest_ip 'fe80::/10'
option dest_port '546'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-MLD'
option src 'wan'
option proto 'icmp'
option src_ip 'fe80::/10'
list icmp_type '130/0'
list icmp_type '131/0'
list icmp_type '132/0'
list icmp_type '143/0'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Input'
option src 'wan'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
list icmp_type 'router-solicitation'
list icmp_type 'neighbour-solicitation'
list icmp_type 'router-advertisement'
list icmp_type 'neighbour-advertisement'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Forward'
option src 'wan'
option dest '*'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config include
option path '/etc/firewall.user'

config rule
option src 'wan'
option dest 'lan'
option proto 'esp'
option target 'ACCEPT'

config rule
option src 'wan'
option dest 'lan'
option dest_port '500'
option proto 'udp'
option target 'ACCEPT'

config zone
option input 'ACCEPT'
option forward 'REJECT'
option output 'ACCEPT'
option name 'guest'
option network 'guest'

config forwarding
option dest 'lan'
option src 'guest'

/etc/config/wireless
config wifi-device 'radio0'
option type 'mac80211'
option hwmode '11g'
option path 'pci0000:00/0000:00:01.0/ssb0:0'
option channel '1'
option txpower '20'
option country 'IT'

config wifi-iface
option device 'radio0'
option mode 'ap'
option network 'lan'
option encryption 'none'
option ssid 'OpenWrt'

config wifi-device 'radio1'
option type 'mac80211'
option channel '11'
option hwmode '11g'
option path 'platform/ehci-platform/usb1/1-1/1-1:1.0'
option txpower '20'
option country 'IT'

config wifi-iface
option device 'radio1'
option mode 'ap'
option ssid 'OpenWrtGuest'
option network 'guest'
option encryption 'none'

/etc/config/dhcp
config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
option localservice '1'

config dhcp 'lan'
option interface 'lan'
option dhcpv6 'server'
option ra 'server'
option ignore '1'
option ra_management '1'

config dhcp 'wan'
option interface 'wan'
option ignore '1'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'

config dhcp 'guest'
option start '100'
option leasetime '12h'
option limit '150'
option interface 'guest'


Notes
  • read risk disclaimer
  • excuse my bad english

OpenWrt Guest Routed AP using VLAN with unmanaged switch

$
0
0
I've previously post about a Routed AP for Guest WiFi isolation based on OpenWrt, you can find that post here: http://davidegironi.blogspot.it/2017/09/openwrt-access-point-routed-ap-as-guest.html

This time I would like to make it a little structured, by simply making it modular.
I will build a Guest router, isolated from the main network, that can be used as a gateway for a Guest wired and wireless network.
My guest network should use the same cabled network of my main network, that is using unmanaged switch. Of course if you have managed switch you will get better perfomance cause you can route the guest network to any guest AP or managed swith you want, but in small office and home network managed switch can't always be found.
Our Guest router will produce one tagged VLAN, let's tag it as '2', that will distrubute our Guest network.
The guest router will also serve as a DHCP server for any guest device.
Note that any AP that we want to make act as a Guest AP must accept VLAN traffic.


The OpenWrt configuration is similar to the one proposed in the previous post linked above.

Once again let's suppose we are serving our main network on 192.168.1.0/24 ip ranges, and we would like a guest network, isolated from the 192.168.1.0/24 one, on the 192.168.2.0/24 ip range.

We will make a new switch, that is new VLAN.

On VLAN 1, we disable port 3 and 4, set 5 untagged
On VLAN 2, we enable port 0 and 3 as tagged, 2 as untagged, set 5 tagged
We are going to use port 2 as a wired guest port, port 3 as a tagged guest port for managed switch, and port 0 is the main port that will get the main network signal and "output" the VLAN 2 tagged signal.

/etc/config/network
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config globals 'globals'
option ula_prefix 'fd6e:e9df:eb78::/48'

config interface 'lan'
option ifname 'eth1'
option force_link '1'
option type 'bridge'
option proto 'static'
option ipaddr '192.168.1.3'
option netmask '255.255.255.0'
option ip6assign '60'
option gateway '192.168.1.1'
option dns '192.168.1.1'

config interface 'wan'
option ifname 'eth0'
option proto 'dhcp'

config interface 'wan6'
option ifname 'eth0'
option proto 'dhcpv6'

config switch
option name 'eth1'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'eth1'
option vlan '1'
option ports '0 1 5'

config switch_vlan
option device 'eth1'
option vlan '2'
option ports '0t 2 3t 5t'

config interface 'guest'
option type 'bridge'
option proto 'static'
option ifname 'eth1.2'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'

/etc/config/firewall
config defaults
option syn_flood '1'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'

config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
option network 'lan'
option masq '1'
option mtu_fix '1'
list masq_dest '!192.168.1.0/24'

config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
option network 'wan wan6'

config forwarding
option src 'lan'
option dest 'wan'

config rule
option name 'Allow-DHCP-Renew'
option src 'wan'
option proto 'udp'
option dest_port '68'
option target 'ACCEPT'
option family 'ipv4'

config rule
option name 'Allow-Ping'
option src 'wan'
option proto 'icmp'
option icmp_type 'echo-request'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-IGMP'
option src 'wan'
option proto 'igmp'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-DHCPv6'
option src 'wan'
option proto 'udp'
option src_ip 'fe80::/10'
option src_port '547'
option dest_ip 'fe80::/10'
option dest_port '546'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-MLD'
option src 'wan'
option proto 'icmp'
option src_ip 'fe80::/10'
list icmp_type '130/0'
list icmp_type '131/0'
list icmp_type '132/0'
list icmp_type '143/0'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Input'
option src 'wan'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
list icmp_type 'router-solicitation'
list icmp_type 'neighbour-solicitation'
list icmp_type 'router-advertisement'
list icmp_type 'neighbour-advertisement'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Forward'
option src 'wan'
option dest '*'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config include
option path '/etc/firewall.user'

config rule
option src 'wan'
option dest 'lan'
option proto 'esp'
option target 'ACCEPT'

config rule
option src 'wan'
option dest 'lan'
option dest_port '500'
option proto 'udp'
option target 'ACCEPT'

config zone
option input 'ACCEPT'
option forward 'REJECT'
option output 'ACCEPT'
option name 'guest'
option network 'guest'

config forwarding
option dest 'lan'
option src 'guest'

/etc/config/dhcp
config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
option localservice '1'

config dhcp 'lan'
option interface 'lan'
option dhcpv6 'server'
option ra 'server'
option ignore '1'
option ra_management '1'

config dhcp 'wan'
option interface 'wan'
option ignore '1'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'

config dhcp 'guest'
option start '100'
option leasetime '12h'
option limit '150'
option interface 'guest'

Now we have to add guest firewall rules for guest interface.
This rule has to accept input, accept output, reject forward and Allow forward to destination zones -> lan, this way all the traffic will be forwared to lan.

The lan firewall rule must have enabled Masquerading and MSS clamping, it also have to Allow forward from source zones -> guest, to accept the forward traffic from guest, and Restrict Masquerading to all subnet but not the 192.168.1.0/24, by the value !192.168.1.0/24.

We can now add a guest interface, as bridge and add the VLAN 2 created on port 3.
We are going to set the guest interface with a static address, and enable DHCP for the guest interface assign the interface to the guest firewall zone.

Now we can set the guest WiFi, binding it to the guest interface.


Now we would have a primary WiFi over our main subnet 192.168.1.0/24, and a guest WiFi + a guest wired connection through port 3 of the router over our secondary subnet  192.168.2.0/24.

The Guest router also can act as a guest AP if we would like, by simply enabling the wifi interface and attaching it to the guest interface.

Now that we have build a Guest router, we have to build a AP guest.
There are a few device that can route VLAN network with stock firmware. If we would like to use an OpenWrt firmware, we must enable a VLAN 2 tagged switch on a port, on the same port the VLAN 1 should be untagged.
Then we have to create a guest interface and a guest firewall rule like we've already done.
We can leave LAN interface unmanaged if we do not need to access this AP by the main network.

That's almost all.

So what we have done now: we have a main Router on our main network on the IP range 192.168.1.0/24 and a Guest router on the IP range 192.168.2.0/24. We can use unmanaged switch and run the guest network by using VLAN tagged packets.


Notes
  • read risk disclaimer
  • excuse my bad english

ST Audio DSP2000 C-Port on Linux using JACK and wineasio

$
0
0
subtitle:
Make revive the ST Audio DSP2000 C-Post audio board on Linux


I've a DSP2000 C-Post Audio System made by ST Audio (http://www.st-audio.de), I'm using it in my small recording room for instruments and voices, then I usually move to my main workstation to mix in a comfortable environment.
Even if it is a card from the late 90s, it still does a pretty decent job.

This system is build of an external unit and a PCI Card.

See main specs below:
  • 10 x 10 24-bit/96kHz 100% Full-Duplex recording path support
  • 2 x balanced (XLR) inputs with built in pre-amps (-24dB to +50dB) & switchable phantom power (48V)
  • 2 x balanced (XLR) outputs
  • 8 x 1/4" unbalanced inputs
  • 8 x 1/4" unbalanced outputs
  • coaxial and optical & AES/EBU I/O connections as standard
  • stereo headphone output with volume control (1/4" connector)
  • 2 x 16 channel (32 channels) MIDI interface ports provided (2 outputs, 1 input)
  • peak LED for channel 1&2
On this card, all the magic happens in the IC Ensemble Envy24 I/O controller chip, nominally the ICE1712.
The problem with this card it that official drivers just work on Windows 9x/Me/NT/2000/XP, unluckly support for those old O.S. is at the end of life.
But we have an ace up sleeve, it is called Linux.
We can make this card revive, using a brand new, and free also, linux distrubution.
The one I've choose it's Linux Mint 18 (http://www.linuxmint.com/).


As workstation I choose the Reaper Digital Audio Workstation (http://www.reaper.fm/). I'm using this station to record, then i will post mix all on my main workstation, using Reaper of course, this time on Microsoft Windows.
I'm using a Intel Core 2 Duo, 4Gg RAM, 256GbHdd as main hardware cause I do not need a lot of power just to record tracks, of course my mixing workstation is a powerfull i5 machine.

Reaper can works on linux thanks to Wine (http://www.winehq.org/).
The ICE1712 alsa module, which is the linux driver that makes the card works, it is already built in the choosen distribution.
The trick here is to use the WineAsio (https://sourceforge.net/projects/wineasio/) wrapper, to make Reaper works on ASIO (https://en.wikipedia.org/wiki/Audio_Stream_Input/Output) through JACK (http://jackaudio.org/).

So, let's dive into my small guide.

Step 1) Install Linux Mint, of course!

Then we have to add install the KxStudio repository (http://kxstudio.linuxaudio.org/). For my x64 Linux Mint distribution, commands below will works
sudo apt-get install apt-transport-https software-properties-common wget
wget https://launchpad.net/~kxstudio-debian/+archive/kxstudio/+files/kxstudio-repos_9.4.6~kxstudio1_all.deb
sudo dpkg -i kxstudio-repos_9.4.6~kxstudio1_all.deb
sudo apt-get install libglibmm-2.4-1v5
wget https://launchpad.net/~kxstudio-debian/+archive/kxstudio/+files/kxstudio-repos-gcc5_9.4.6~kxstudio1_all.deb
sudo dpkg -i kxstudio-repos-gcc5_9.4.6~kxstudio1_all.deb
sudo apt-get update
sudo apt-get upgrade

VST and wineasio works on x86, so let's set our architecture
sudo dpkg --add-architecture i386

Now we are going to install jack, realtime mode is preferred, when installation ends make the current user part of the audio group using "Administration / Users and Groups: , then logout and login again on your session
sudo apt-get install jackd jack-tools

Commands below will install wineasio, and also wine-rt that is a dependance on wineasio.
sudo apt-get install wineasio
This command will register wineasio, id successfull it should return something like "Successfully registered DLL wineasio.dll"
regsvr32 wineasio

The mudita24 (https://github.com/NielsMayer/mudita24) mixer and alsa-tools should help configuring our card
sudo apt-get install alsa-tools
sudo apt-get install mudita24


Finally, we can install Cadence from the KxStudio tools to enable the ASIO driver.
sudo apt-get install cadence
Once Cadence is installed we have to set the device binded to the driver to Alsa / hw:DSP24.
Then make autostart JACK daemon, and also it could be usefull to route ALSA and PulseAudio to Jack, simply settings the ALSA Bridge to ALSA->Jack

A reboot is preferred now.

Reaper should now recognise the card using the wineasio driver, all should work fine, at least on my hardware.

This card still rules, and can be used at least to record up to 8 tracks.


Notes
  • read risk disclaimer
  • excuse my bad english

Small office backup and datastore environment

$
0
0
This post is about my small office datastore and backup enviroment, because "Shit Happens! It's the way you handle it that matters" (cit. Pete Vinken).

My main data store is a pretty old NAS, a Zyxel NSA320, with 2Tb in RAID 1.
I use that NAS for archived jobs, pictures, documentations, downloads, and things that I not often use.


This NAS can install packages from a zyxel offical repository.
A few usufull packages I suggest are:
  • NFS: install NFS server features
  • TFTP: add a TFTP server
  • SMART: Use S.M.A.R.T. (Self Monitoring, Analysis, and Reporting Technology) to monitor hard disks.
If you would like to hack it a bit, you can install a new repository, using instruction from: http://zyxel.nas-central.org/wiki/3rd_party_zypkgs
Once the repository was installed, I've just added a few packages:
  • Dropbear: now I can access the SSH without using any trick, I'm talking about this one http://zyxel.nas-central.org/wiki/Telnet_backdoor
  • RandomTools: some random tools like unrar, nano and so on
  • Tweaks: usefull tweaks like the crontab, a shutdown daemon and so on
  • Entware-ng: the Entware-ng package system, then I've installed
    • openssh-client
    • openssh-server
    • rsync
I use my developement PC as a data store for jobs not archived and that I often use.

My main backup store it is build around two NetGear Stora NAS I've laying around.
The main changes I've made are:
That two store are in my garage. One thing i like from the Stora is that is spin down disk, so power consumption is being reduced.


The four drives on my two store are used for:
  1. my hypervisor backup
  2. Zyxel NSA320 mirror backup
  3. desktop and laptops backup
  4. not used
In a previous post I've talk about my hypervisor and hosts backup, you can find it here: http://davidegironi.blogspot.com/2017/06/vsphere-esxi-backup-strategies-for.html.

The Zyxel NSA320 backup consists of a bash script that uses rsync to mirror the entirire NAS volume over a NFS folder.
In order to make this backup works you have to make a NFS share on a remote device.
Create a share for administrators, this one is optional, you can even put this in your admin share, for now let's suppose the administrators path to be /i-data/______/administrators.
Create a backup folder for data and bin on your Zyxel
$mkdir /i-data/______/administrators/backups/bin
$mkdir /i-data/______/administrators/backups/data
Copy the backup.sh script to the backups/bin folder.
Make the script executable for all users
$chmod a+x /i-data/______/administrators/backups/bin/backups.sh
Edit the script preferences according to your enviroment, you can as example use vi
$vi /i-data/______/administrators/backups/bin/backups.sh
Add the script to crontab, you can access the crontab by the Tweaks package. As example, if you would like to run the script at 2 o'clock at day 5 of week, and have the backup status returned to a txt file, just add the line below to your crontab
  0 2 * * 5 /i-data/______/administrators/backups/bin/backup.sh > /i-data/______/administrators/backups/bin/lastbackupstatus.txt 2>&1

Find the backup script below:
#!/bin/sh

#preferences
LOCALSOURCE=/i-data/_______/
LOCALDESTINATION=/i-data/_______/administrators/backups/data
NFSMOUNTHOST=backupnas
NFSMOUNTPOINT=/home/_______/backups/NAS320

echo "Running backup"
echo ""

#unmount
umount $LOCALDESTINATION
#mount
mount.nfs $NFSMOUNTHOST:$NFSMOUNTPOINT $LOCALDESTINATION -v -o nolock
#check if is mount
if [[ $(nfsstat -m | grep -A 1 $NFSMOUNTPOINT | head -c1 | wc -c) -ne 0 ]]; then
echo "NFS folder $NFSMOUNTHOST:$NFSMOUNTPOINT mounted on $LOCALDESTINATION"
echo ""
rsync -rltxuv --delete $LOCALSOURCE $LOCALDESTINATION
else
echo "Error: can not mount NFS folder $NFSMOUNTHOST:$NFSMOUNTPOINT to $LOCALDESTINATION"
fi

#umount
umount $LOCALDESTINATION

Note that this script mount the NFS location instead of using rsync over NFS or rsync over ssh. That's because I've notice a better trasfer performance working that way, I'm talking of almost 10Mb/s.

On my developement PC I use two software for backup.
  • Create Synchronicity: find it here http://synchronicity.sourceforge.net/. To mirror the VMWare machines of my development pc over a shared folder. This can be used to syncronize data that does not need to be incremental.
  • Duplicati: find it here: https://www.duplicati.com/. To backup data of my pc over a shared folder. I set up Duplicati with a regex that backups each Project* and Documents* folder, that way all the folder on my main mounted environment that starts with that prefix are been backupped. I can create a new Project tree, like "Projects ESP8266", and that would be added to my backups. Duplicati performs incremental backup, allowing me to reastore data older that 30 days. 
That's almost all about my actual datastore and backup environment.


Notes
  • read risk disclaimer
  • excuse my bad english

esp8266/Arduino NTC library

$
0
0

A thermistor is a type of negative coefficient resistor whose resistance is dependent on temperature, more so than in standard resistors. The resistance of a NTC Negative Temperature Coefficient thermistor (https://en.wikipedia.org/wiki/Thermistor) decreases as temperature rises. The Steinhart-Hart Thermistor Equation or the Beta Model Equation can be used to correlate the thermistor resistance to temperature to which the sensor is exposed.

The library implements the Steinhart-Hart Thermistor Equation or the Beta Model Equation to convert adc value read from analog input to temperature.
It output temperatures in Celsius or Fahrenheit.

The ESP8266 comes with a 10bit ADC, 0 to 1V, one can use the ESP8266 ADC for this library.
Suppose you are going to the internal ADC, and that NTC is going to be used between -20 and +100 degree Celsius. The NTC resistance by datasheet at -20 degree is 100k, and at 100 degree 100. To evaluate the pullup resistor you have to consider that the Voltage output at the ADC pin will be
Vout = Vpullup*(Rntc/Rntc+Rpullup)
We have to consider the max Vout, that comes from the max resistance given by the NTC
Voutmax = Vpullup*Rntcmax/(Rntcmax+Rpullup)
We have to chose a Rpullup such that Voutmax < 1V, so:
Rpullup = Vpullup*Rntcmax/Voutmax - Rntcmax
Subsitute with the sample NTC we are considering:
Rpullup = 3.3*100000/1 - 100000 = 230000.
A 220k resistor would do the job.

In the example i propose here I am using a ADS1015 12 bit analog to digital comparator, that is much more accurate than the internal ESP8266 ADC.
I am using the Adafruit ADS1X15 library for this IC, on top of that library I've build an helper to just convert the ADC raw value that comes from the ADS1x15 to a resistance or voltage value.


Once we've acquired the NTC resistance we can use the Steinhart-Hart Thermistor Equation or the Beta Model Equation to convert the resistance value to temperature.

A digital iir filter is implemented to remove unwanted reading errors.

This library was developed on Atom+PlatformIO, compiled esp8266/Arduino.

Code

Notes
  • read risk disclaimer
  • excuse my bad english

esp8266/Arduino 74HC4051 library

$
0
0

The 74HC4051 is a high-speed Si-gate CMOS device and is pin compatible with Low-power Schottky TTL (LSTTL).

The 74HC4051 IC can be used to expand the single ADC input port of the ESC8266, to 8 ports.
The ESP8266 comes with a 10bit ADC, 0 to 1V, the datasheet doesn't tell much more than this about the internal analog converter.


The output pin of the 74HC4051 is controller by 3 pins, by setting those pins high or low an analog input of the 74HC4051 is selected.
It can be driven by the same 3.3V that powers up the ESP8266.


This library was developed on Atom+PlatformIO, compiled esp8266/Arduino.



Code

Notes
  • read risk disclaimer
  • excuse my bad english

An AVR ATmega R/C control signal reader - Method/02

$
0
0

The Radio Control (R/C or RC) is the method of controlling remote devices using radio frequencies.
Most of the time the RC signal uses RC servo signals.
Servo signal is a square PWM signal, usually with a period of 20ms and a duty time between 1ms and 2ms. More info on the wikipedia page here: https://en.wikipedia.org/wiki/Servo_control.

This library implements a method to read an RC signal and eventually map this to a 0..100 number.

There are a few methods of performing this task of course. Another alternative method i propose can be found here: http://davidegironi.blogspot.com/2017/04/an-avr-atmega-rc-control-signal-reader.html


It's developed on an ATmega8 running at 16Mhz.
It makes use of the external interrupt PIN and a timer to count the duty period time.
It's customizable to fit the user preferences. Configuration can be found in rcin2.h header file.
This is slighly less accurate than the Method/01 proposed in the link above, but it uses less resources due to the slower timing needs.
Theory of operation: each time a rising edge interrupt it is raised the timer counter is stored, When the falling edge happens the difference between the actual timer counter and the stored one it is used to compute the duty time.
Input PIN is INT0.
The RC signal it is measured, eventually filtered using an exponential moving average filter, and then mapped to a speed value from 0 to 100.


Code
Notes
  • read risk disclaimer
  • excuse my bad english

A web configurable ThingSpeak logger, build on AVR ATmega328

$
0
0
ThingSpeak is an open source Internet of Things (IoT) application and API to store and retrieve data from things. It is an on-line database service allowing developers to connect sensor-derived data (e.g. energy and environment data from objects, devices & buildings) to the web and to build their own applications based on that data.

This embedded platform is a modular and configurable ThingSpeak data logger, built on an ATmega328 micro, usefull to send datapoints to your ThingSpeak feed.


This project is an update to the Xively logger presented here: http://davidegironi.blogspot.com/2014/12/a-web-configurable-xively-logger-build.html.
LogMeIn will retire this legacy version of Xively, that is Xively Personal, on January 15, 2018. For this reason I've made an update to my previous logger in order to update my products logger to ThinkgSpeak.

If you are going to use this logger, please read the linked post link about the Xively version. This version is almost identical to the Xively one, just a few things has been changed to meet the ThingSpeak RESTful API.

The POST method it is used to send data to Thinkgspeak.
Even this version has a network interface you can use to configure the Ip address and connection mode, and your ThingkSpeak API key and feed number.

If you are using the priouse version you have to update the main.c and main.h code files, and the _xivelygetdata methods of you sensors implementations, this function has been renamed to _thingspeakgetdata. Also, all the previous reference to xively has been renamed.

The hardware used is an ATmega328, running at 16Mhz, for this reason one can also use an Arduino board. The network board used is based on the EC28J60 IC.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

UV Sensor ML8511 AVR Atmega library

$
0
0

Ultraviolet (UV) is an electromagnetic radiation with a wavelength from 10 nm to 400 nm.
The ML8511 is an ultraviolet sensor that output an analog signal correlated to the amount of UV light detected. By datasheet the sensor detects wavelength from 280nm to 560nm.


Here I've implemented a driver for AVR Atmega, portable to other microcontrollers, that correlates the sensor output to light intensity, it also computes the UV index based on the sensor input.
The ultraviolet index or UV index is an international standard measurement of the strength of sunburn-producing ultraviolet (UV) radiation at a particular place and time. It is a linear scale, with higher values representing a greater risk of sunburn. The purpose of the UV Index is to help people effectively protect themselves from UV radiation.
Not all the energy of the UV spectrum has the same "damage" power, due to this the power spectrum is multiplied by a weighting curve known as the erythemal action spectrum, and the result integrated over the whole spectrum.

The correlation function I propose here is derived by the datasheet graph of "Output Voltage over UV intensity".


From this graph we can get the correlation function. This graph is clearly a linear function. We have Output voltage on the y axis and UV intensity on the x axis.
Because we want to obtain the UV intensity using the voltage that we can read from the sensor, we are going to flip the graph.


Once we have flipped the graph we can now get the point from the graph using a tool like WebPlotDigitizer.
We can now use liner regression technique to obtain the function we need to convert voltage output to UV intensity.
Also notice that this graph has four functions for 75degree, 25degree, -5degree, -25degree temperature condition.
If we perform linear regression on points of that function we get 4 correlation functions.

@75deg UV mW/cm2 = 8.158154634V -7.77772054
@25deg UV mW/cm2 = 7.9816914V-7.921745308
@-5deg UV mW/cm2 = 7.853758854V - 7.934095316
@-25deg UV mW/cm2 = 7.743732684V - 7.978602568

Note thate the accuracy of this method depends on the accuracy of your point extraction.

More in general we can say that the correlation function looks like this:


If we are going to use this sensor under different thermal condition we can simply interpolate beween those function to get the correlation function slope "s" and intercept "i".

Also, that graph is for a wavelength of 365nm.
We may find the responsivity function of this sensor on the datasheet. Responsivity measures the input–output gain of a detector system. We can use again the WebPlotDigitizer to find points from the "Responsivity Characteristics" curve.


We may notice that for the 365nm light the responsivity is 1. It means that on that light condition the sensor correlation function we have seen before has a gain of 1.
If we suppose to apply a filter over the sensor UV detector that passes only just a single wavelength we can adjust the correlation function according to the gain of the sensor responsivity. That function is inversally proportional, so if our sensor has responsivity 0.3 on a 400nm wavelength, the correlation function have to be multiplied by 1/0.3, cause the voltage output measured is 0.3 times less than the voltage output at 365nm.
We are not going to use this most of the time, because we are going to use our sensor to measure the total UV intensity.

Now let's take a look at the UV index.
The UV index is defined as:


The function that defines the susceptibility of the human skin to sunburn (erythema) and of generalised DNA damage due to UV radiation is called erythema function, you can find it below.


Given the erythema function w(lambda)


And the irradiance spectrum I(lambda), we may note that the 1/25 coefficients makes the UVI dimensionless.

We have tell that the sensor we are using measures ultraviolet intensity between a range.

We are going to consider just:
  • Ultraviolet A (UVA): wavelength between 315nm and 400nm
  • Ultraviolet B (UVB): wavelength between 280nm and 315nm
We can assume a fixed ratio between UVA and UVB because we know that more than 95% of the ultraviolet radiation that reaches the Earth's surface is the UVA. So we can say


And, because this sensor measure just UVA and UVB, we can also say


and


Our sensor gives us a voltage output.

To make math simpler we can average the erythemal function w(lambda) for UVA and UVB as follows:


Now, we can take a look to the UV index function, we notice it as a mW/m2 index, so we have to covert the correlation function to mW/m2


Then we can substitute things in there:


We finally get


As example, if we consider a fixed temperature of 25degree, we get:


If you have a calibrated UV index meter you can correlate that function with the meter and adjust the offset of this equation.


Where o is the offset calculated using the equation


Reference: "Ultraviolet Sensor IC with Voltage Output by ROHM and LAPIS semiconductor". Note that on that paper they use a different method of correlation to find out the correlation curve.

In conclusion we have take a look at this UV sensor, trying to correlate the sensor output to the UV intensity, eventually considering also the environment temperature.
We have then looked at the UV index function, which is fairly usefull as an index for UV impact on health.

This library have been developed on an ATmega8 running at 1Mhz.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

TriNegistor, a Triple Negistor oscillator noise box

$
0
0
-- ref. 2010


This box I present here is a triple negistor oscillator. This is basically a noise box I use to make sounds.


The orignal schematics cames from Charlie Barth trinegistor, you can find it here http://moosapotamus.net/trinegistor.html.


I just change some components and add a few switch to his schematics.
First of all, what's a Negistor? It's a a NEGative dIfferential resistance oscillaTOR, it's an oscillator built using his NDR effect. The negistor I use it's build using a 2N2222A NPN transistor wired in reverse mode. Please find more information here: http://www.keelynet.com/zpe/negistor.htm.
The tri-negistor is built putting in series three negistor oscillator.


Notes
  • read risk disclaimer
  • excuse my bad english

DentneD: an open source Dental Practice Management Software

$
0
0
DentneD is a Dental Practice Management Software.
It's a complete open source solution to manage you clinic.


You can trace your patient, treatments, scheduling appointments, doing reports, and billing managment.
It features a client-server architecture.

Features:
  • Doctors records, manage more than one dentist
  • Patient records
  • Full patient medical records
  • Patients attachments and notes management
  • Billing management, with invoices and estimates
  • Treatments lists
  • Scheduling agenda
  • Customizable reports
  • PDF output templates
  • Cloud backup scripts
  • Calendar web interface
  • Client-server architecture, access by multiple computer at the same time
  • Multilanguage
  • Send appointments reminder
  • Password form protection
  • Windows service for additional features
Requirements:

  • Microsoft Windows with .NET framework 4.5.2 or later
  • Microsoft SQL Server 2012 or later
  • For web app: PHP 5.3 or later
Code & Releases









Notes
  • read risk disclaimer
  • excuse my bad english

4pin hall sensor adapter board

$
0
0

Hall Sensor are pretty common components. Most of the time one will find 3 pin Hall Sensor. But there are time that one can find a 4 pin hall sensor.
Those kind of sensor is called dual-channel.


They basically have GND and VCC input, then two output. When a magnetic field is applied a small voltage happears between the two output, reversing the direction of the applied field will reverse the voltage output.
If you want to use that sensor as a switch you have to build a comparator circuit that ouput a signal level.
As example, in old cdrom brushless motor those kind of hall sensor are common. To use an old cdrom as a rotary encoder, or to connect the cdrom to a brushless sensored driver, you need to convert the output of the 3 hall senso monted on the cdrom in a logic signal output.
The circuit proposed here use a differential comparator to achieve this goal.
Here you can find the schematic and a board design for this circuit, in Eagle format.





Schematics & Board


Notes
  • read risk disclaimer
  • excuse my bad english

MCP4725 DAC AVR ATmega library

$
0
0

In this post I present an AVR implementation for the MCP4725 DAC.

The MCP4725 DAC is a pretty common and cheap single channel 12 bit buffered voltage DAC, it also has an onboard EEPROM.
To drive this chip we can use I2C interface.



The ATmega8 used for my implementation has an embedded I2C interface, so we just can use that interface.
The selected I2C library is the one proposed by Peter Fleury, you can find it here: http://homepage.hispeed.ch/peterfleury/avr-software.html

To library provides simple functions to set the output channel of the IC by using raw value or a voltage value.


The voltage output of this chip is limited by his voltage input, that is 2.7v to 5.5v, and the current allowed at the output pin is 25mA.
If you need more current, or more voltage, you can use a combination of opamp and power transistors.

Up to 8 MCP4725 can be driven using this library, the IC address has to be selected using the hardware pulldown selector.

This project has been developed and tested on an ATmega8 running at 8Mhz.

An example program is provided in order to help the library usage.



Code

Notes
  • read risk disclaimer
  • excuse my bad english

Switch debounce library

$
0
0


Contact bounce (ref. https://en.wikipedia.org/wiki/Switch#Contact_bounce) is a common problem with mechanical switches and relays. Switch and relay contacts are usually made of springy metals. When the contacts strike together, their momentum and elasticity act together to cause them to bounce apart one or more times before making steady contact.

You can find below a sample of a bouncy button press. You can see the typical ripples of the bounce button press.



If you use a microcontroller to read the button status, depending on the speed you read the button it may seems that it is pressed many times, even if it is pressed once, and that's should became a problem.

To solve this issue there are two way:
  • Hardware
  • Software
The usual hardware way is to build a low pass filter. Sometimes you will find a Schmitt-trigger after the RC filter, to avoid hysteresis.
The limitation of the hardware way is that you have to implement it on your board, to select the correct component values, and to use more hardware.
A software solution may help us, providing a malleable way to solve this issue.

An interesting reading about this topic is the Jack Ganssle's article "A Guide to Debouncing"http://www.ganssle.com/debouncing.htm

Also, I suggest you to take a read at the two articles series by Elliott Williams, he explains this issue very well and also propose a few hardware and software solutions:
The library i propose here is of course a software solution, developed on ATmega microcontroller but portable to many other micros.

It is based on the Trent Cleghorn code you can find it here: https://github.com/tcleg that is an implementation of the Jack Ganssle article posted above.

What it pratically does is to read the button status a bounch of time, and set the final status button only if all the times the reading was done is the same.
Ganssle by experiments analyse that a value from 10ms to 20ms is enough to consider stable a button output. In my example I read 8 times the button each 10ms, but one can also use less time without problem.

The library works by byte status, it means it can debounce multiples of 8 buttons at time, one for each bit. Therefore a 2 byte implementation can debounce 16 buttons.

There are function for to get the press and release button, and the current status. Press and release functions also are implemented in such a way that one can read that function and arm back that function status only after it is read.



Code

Notes
  • read risk disclaimer
  • excuse my bad english

An interrupt free quadrature decoder library for rotary incremental encoders

$
0
0


A rotary incremental encoder, also called a shaft encoder, is an electro-mechanical device that converts the angular position or motion of a shaft or axle to analog or digital output signals (https://en.wikipedia.org/wiki/Incremental_encoder).

That kind of encoders may use mechanical or electronic sensors to read the rotation steps.
They have got two output channel, let's call that A and B.
When the rotary move at a fixed speed, they produce a quadrature-encoded output, that means the duty cycle of each pulse is 50%.

This library is an implementation of a quadrature decoder, that is a device that reads A and B channel output from an encoder and produce a direction and step count signals.

Rotary encoders may be of two types, one for hand use, with fixed rotation point that the user can feel, other for motors or rotative devices, with no rotation fisical step. This driver does not work well with rotary encoder with fixed point on step change, however that types of encoder is not common.


To decode the encoder status we have to build a state machine that implements the quadrature decoder table you find below.

Once that table is implemented, to avoid step missing we need to read the channels status with an appropriate speed. That speed might be 127 times more than the channels changing speed. For a manual rotary encoders 1ms reading time is enought, it means that we can read the channel change status at the frequency of 1kHz/127 = 8Hz.

This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 1MHz.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

Debian and OpenMediaVault on Zyxtel NSA310 using Kirkwood U-Boot and Kernel

$
0
0
I've a Zyxtel NSA310 NAS laying around that sometimes does not boot.
This was an inspiration for me to try installing Debian on this kind of device.
On the NAS central web page you can find a lot of usefull information about this NAS. I'm speaking of the following page: http://zyxel.nas-central.org/wiki/Category:NSA-310


If you are planning to install Debian on a NAS device, a good place to look at is the doozan forum.

This is my brief instruction, that I've extract from the doozan forum, to install Debian and OpenMediaVault to this NAS.

Warning! Updating your NAS following this instructions may brick your device. Everything you do at your own risk.

First of all a quick investigation on this device reports that the booting problems I encountered was caused by nand bad sectorson the kernel_1 mtd.

The process consists of three steps
  1. install the u-boot
  2. install the rootfs - Debian system
  3. setup Debian
Step 1) install the u-boot and u-boot environment
This is the dangerous part. Updating the mtd0 partition may brick your device.
In order to install Debian on this device, we have to load the kirkwood uboot.
You can download the latest version of the kirkwood uboot for NSA310 from this doozan forum page: https://forum.doozan.com/read.php?3,12381. The one I'm using is uboot.2017.07-tld-1.nsa310.bodhi.tar.
Also download the environemnt file, which is uboot.2016.05-tld-1.environment.bodhi.tar

Remember to check the MD5 value for those files with the one provided at the doozan forum. If they match untar that files.
To makes things simpler rename the uboot to uboot.kwb and environment file to uboot.img
For me that is done with the command:
mv uboot.2017.07-tld-1.nsa310.mtd0.kwb uboot.kwb
mv uboot.2016.05-tld-1.environment.img uboot.img

We are going to install the uboot on the mtd0 partition.
To check your partitions login to the ssh shell of your NSA and run the following command
cat /proc/mtd

The mtd partitions of your NSA310 should look like this:
dev:    size   erasesize  name
mtd0: 00100000 00020000 "uboot"
mtd1: 00080000 00020000 "uboot_env"
mtd2: 00080000 00020000 "key_store"
mtd3: 00080000 00020000 "info"
mtd4: 00a00000 00020000 "etc"
mtd5: 00a00000 00020000 "kernel_1"
mtd6: 02fc0000 00020000 "rootfs1"
mtd7: 00a00000 00020000 "kernel_2"
mtd8: 02fc0000 00020000 "rootfs2"

You should backup your mtd0 partition, just in case.
To dump your partition download the uboot tools from this page https://forum.doozan.com/read.php?3,27280 extract it to a folder of your NAS, it may be a shared one, jump to that folder using your terminal, and run the following commad:
nanddump --noecc --omitoob -l 0x80000 -f mtd0 /dev/mtd0

It should have built the mtd0 file, which is your original mtd0 partition.
You should also save your actual env running:
fw_printenv > current_envs.txt
This time the current_envs.txt file is the environments variables content.

Now that you have dumped your actual configuration, before loading the new u-boot you MUST check that your device does not have bad sector on the mtd0 partion, running the command:
dmesg | grep -i 'bad'

We are going to use a usb key to load the uboot to your NAS.
FAT format a usb key. Copy the uboot.kwb and uboot.img files to your key.
Connect your NAS using an UART adapter. The baudrate you have to use it's 115200.
Boot your NAS up, you should see a message on your UART terminal asking to press any key to interrupt the boot process, so press that key.
Now you are in the u-boot command terminal.
Plug the USB key and load the kernel to ram
fatload usb 0 0x0 0x800000 uboot.kwb
If it's all ok, you are ready to erase the nand for mtd0 partition
nand erase 0x0 0x1000000
then write then new uboot
nand write.e 0x800000 0x0 0x100000
Now load the usb uboot_env
fatload usb 0 0x0 0x800000 uboot.img
and write the uboot_env
nand write 0x800000 0xc0000 0x20000
Run printenv for test purpose
printenv
and save environement
saveenv
Cross your finger and reboot using command
reset

If it reboot you can now set environments. Once again press enter to jump in the uboot terminal.
Run the following command in order to properly set environment
setenv arcNumber 4022
setenv machid
setenv mtdparts 'mtdparts=orion_nand:0x100000(uboot),0x80000(uboot_env)'
then save environement
saveenv
and reboot
reset

2) install the rootfs - Debian system
Now you can install the Debian system. This is going to be simpler then the uboot installation.
Download the latest Debian kirkwood rootfs from this link: https://forum.doozan.com/read.php?2,12096
I'm running Debian-4.12.1-kirkwood-tld-1-rootfs-bodhi.tar.bz2
My choice is to run the Debian distribution on a 8Gb usb key, and use the NSA hard drive as storage.
Format a usb key in ext3, you also can format it as ext4 with the newer kirkwood boot but to me ext3 is enough, and set the label of this disk as "rootfs".
Mount the usb key and login as root in your terminal, you must be logged as root, the sudo command is not enough.
Copy the bz2 file your have download to your key.
Jump to the usb root mount folder, and extract the file. For me it's the command:
tar -xjf Debian-4.12.1-kirkwood-tld-1-rootfs-bodhi.tar.bz2
Now edit the file etc/network/interface cause eth0 will be named enp1s0 on NSA310 as follow:
  auto enp1s0
  allow-hotplug enp1s0
  iface enp1s0 inet dhcp
Plug the usb key to the NSA310 and boot it.

The NSA should boot up with Debian.
If you set your network interface as above you should found it on your DHCP leases.
You should be able to log in the ssh terminal using the default username and passwod: root for both.

One logged in renew the ssh keys by using the following 
rm /etc/ssh/ssh_host*
ssh-keygen -A
apt-get update
apt-get upgrade

And change your root password using passwd.

You are now ready to install things on your Debian NAS.

3) setup Debian
The most usefull software you can install in your NAS, to me, it's OpenMediaVault.
Installing OpenMediaVault in your new NAS is really simple, you just have to add the openmediavault repository package, using the command:
cat <<EOF >> /etc/apt/sources.list.d/openmediavault.list
deb http://packages.openmediavault.org/public arrakis main
# deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis main
## Uncomment the following line to add software from the proposed repository.
# deb http://packages.openmediavault.org/public arrakis-proposed main
# deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis-proposed main
## This software is not part of OpenMediaVault, but is offered by third-party
## developers as a service to OpenMediaVault users.
# deb http://packages.openmediavault.org/public arrakis partner
# deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis partner
EOF

Then run the following come to install the openmediavault software:
export LANG=C
export DEBIAN_FRONTEND=noninteractive
export APT_LISTCHANGES_FRONTEND=none
apt-get update
apt-get --allow-unauthenticated install openmediavault-keyring
apt-get update
apt-get --yes --auto-remove --show-upgraded \
    --allow-downgrades --allow-change-held-packages \
    --no-install-recommends \
    --option Dpkg::Options::="--force-confdef" \
    --option DPkg::Options::="--force-confold" \
    install postfix openmediavault
# Initialize the system and database.
omv-initsystem

Now you should be able to login to the web interface of your NSA310 openmediavault using the default username and password, that are admin and openmediavault.

From the OpenMediaVault panel you can set the static address of your network card, of course you can to this by terminal also.
You can format and mount your hard drive, and setup your sharing.
You can find a lot usefull information on the openmendiavault documentation page https://openmediavault.readthedocs.io/en/latest/

Notes
  • read risk disclaimer
  • excuse my bad english


Usa a MCP23017 GPIO port expander with an ATmega

$
0
0

The MCP23017 is a general purpose I/O port expander, it is driven using the I2C interface.
Each of the 16 channels can be set independently as an input or as an output pin.

This library provides functions to drive up to 8 MCP23017, it means you can expand your micro to 128 between input and output.


One of the interesting feature of this IC is the possibility to set an interrupt.
Interrupts can trigger a change on both INTA and INTB chip output, if mirror mode is selected a change on the bus A, or B trigger interrupts on both INTA and INTB.
One can also set the polarity of the interrupt, it means if the input gives you a high or low level on output.
Output interrupt channel can also be set as open drain.
You can set interrupt on each individual input channel, setting the compare mode, i.e. if the pin status has changed since the last reading, or if the pin has changed compared to a value set by the user. This last option is usefull if you want as example to set the comparation for rising or falling mode.
Then the interrupt can of course be enabled just for a single pin.

This interrupt features gives you the ability to quickly detect the change on a pin.

This library also provides function to set each individual pin mode as input or output, output pin status and read input pin status. Functions to read group of values for the full A or B channels as byte are also provided.


This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 1MHz.

If you want further information on that IC, i suggest you to take a look to that two interesting articles on that IC:


Code

Notes
  • read risk disclaimer
  • excuse my bad english

Viewing all 196 articles
Browse latest View live