Alle Beiträge von starcalc

Mining Monero on old Ubuntu

Getting the xmr-stak-cpu to work on an ubuntu 14.04:

* Compile gcc from scratch and install to /home/user/inst (script)

#!/bin/bash
VER=7.1.0
cd
WORKDIR=${PWD}/work/gcc-${VER}
INSTDIR=${WORKDIR}/inst
mkdir -p ${WORKDIR}
mkdir -p ${INSTDIR}
cd ${WORKDIR}
if [ ! -e gcc-${VER}.tar.bz2 ]; then
	wget -O gcc-${VER}.tar.bz2 ftp://ftp.gwdg.de/pub/misc/gcc/releases/gcc-${VER}/gcc-${VER}.tar.bz2
fi
if [ ! -e gcc-${VER} ]; then
	tar xvfj gcc-${VER}.tar.bz2
fi
cd gcc-${VER}
./contrib/download_prerequisites
# 64bit only
./configure --disable-multilib --prefix=/home/user/inst && make -j $(grep -c ^processor /proc/cpuinfo) && make install

* Compile cmake from scratch

cd
mkdir -p work
cd work
mkdir -p cmake
cd cmake
wget https://cmake.org/files/v3.8/cmake-3.8.2.tar.gz
tar xvfz cmake-3.8.2.tar.gz
cd cmake-3.8.2.tar.gz
./configure --prefix=/home/user/inst && make && make install

* Download the xmr-stak-cpu files and compile

mkdir -p $HOME/work/xmr
cd $HOME/work/xmr
git clone https://github.com/fireice-uk/xmr-stak-cpu
cd xmr-stak-cpu
CC=$HOME/inst/bin/gcc CXX=$HOME/inst/bin/g++ PATH=$HOME/inst/bin:$PATH cmake . -DCMAKE_INSTALL_PREFIX=$HOME/xmr-stak-cpu -DMICROHTTPD_REQUIRED=OFF && make && make install

This will compile the file with the new gcc and the new cmake. The result will be installed to $HOME/xmr-stak-cpu, it’s only the executable file and the config.txt.

To run, you must point your LD_LIBRARY_PATH to the correct directory, otherwise you’ll get strange errors:

LD_LIBRARY_PATH="$HOME/inst/lib64" ./xmr-stak-cpu

Arduino als JTAG Programmer

Ich würde gerne meine Honeywell Heizkörperregler HR-20 Rondostat zeitgesteuert nicht nur passiv auslesen (das geht auch schon mit der nativen Firmware), sondern auch über einen ESP8266 steuern. Das wurde schon von schlauen Leuten vorgedacht, und daher gibt es mit OpenHR20 auch eine neue Firmware, welche man mittels JTAG-Interface auf das HR20 flashen kann.

Ich habe nur kein JTAG-Programmierer zur Hand, aber dafür einen Arduino Uno. Ich habe den Ansatz eines JTAGduino gefunden. Die notwendigen Lötarbeiten waren schnell erledigt, ich habe die nachfolgende Steckerbelegung (Quelle) berücksichtigt, um den JTAGduino zu versorgen. Um eine durchgehende Stiftleiste am Arduino Uno verwenden zu können, habe ich die gesamte Kommunikation auf die Analogen Ports A0 bis A4 gelegt.

Die ersten Tests mit den von JTAGduino mitgelieferten Skripten verliefen erfolgreich, wenn ich das JTAG-Interface vom Arduino an den HR20 angeschlossen habe und mein Arduino an meinen Linux-Rechner per USB verbunden ist, kommt folgende Ausgabe:

user@host:~/work/JTAGduino$ ./host_test.py 
if_ver_major = 0; if_ver_minor = 1
fw_ver_major = 0; fw_ver_minor = 1
set_serial_speed(115200) = 0
clear pin TDI rsp = 1
set pin TDI rsp = 0
get pin TDO rsp = 0; val = 0
jtag_clock(1,1): rsp = 1; tdo = 0
jtag_clock(1,0): rsp = 0; tdo = 1
jtag_sequence([1,1,1,1], [1, 1, 0, 1]), rsp = 0; tdo_seq = [1, 0, 0, 0]
jtag_sequence([1] * 255, [1] * 255), rsp = 0; tdo_seq = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
device.set_jtag_speed(1) = 255
jtag_sequence([1] * 255, [1] * 255), rsp = 127; tdo_seq = []
user@host:~/work/JTAGduino$ ./readid.py 
Traceback (most recent call last):
  File "./readid.py", line 81, in 
    if rsp != 0: raise Exception('error: set_jtag_speed returned %d' % rsp)
Exception: error: set_jtag_speed returned 191
user@host:~/work/JTAGduino$ ./readid.py 
#Taps = 1
Device identifier registers (beginning from closest to TDO):
0x6940503F

Die Fehlermeldung habe ich absichtlich drin gelassen, damit man auch andere den Grund für den Fehler finden können. Man muss vor JEDEM Ansprechen des JTAGduino diesen manuell auf durch einen Druck auf den Reset-Button am Arduino zurücksetzen.

Die ID 0x6940503F ist bereits die vom HR20, wir können also grundsätzlich per JTAG bereits mit ihm kommunizieren.

Als nächstes muss ich noch herausfinden, wie avrdude mit dem so gebauten „Programmer“ sprechen kann, bisher habe ich nur ermitteln können, dass es eine mögliche Liste von Programmern in avrdude vordefiniert gibt: (Der Pfad zur Arduino-Installation muss natürlich angepasst werden)

user@host:~/work/JTAGduino$ PATH=$PATH:/arduino-1.8.1/hardware/tools/avr/bin avrdude -c dslfkj -C /arduino-1.8.1/hardware/tools/avr/etc/avrdude.conf 2<&1 | grep -i jtag
  atmelice         = Atmel-ICE (ARM/AVR) in JTAG mode (avrdude: jtag3_open_common(): JTAGICE3/EDBG port names must start with "usb")
  dragon_jtag      = Atmel AVR Dragon in JTAG mode
  jtag1            = Atmel JTAG ICE (mkI)
  jtag1slow        = Atmel JTAG ICE (mkI)
  jtag2            = Atmel JTAG ICE mkII
  jtag2avr32       = Atmel JTAG ICE mkII im AVR32 mode
  jtag2dw          = Atmel JTAG ICE mkII in debugWire mode
  jtag2fast        = Atmel JTAG ICE mkII
  jtag2isp         = Atmel JTAG ICE mkII in ISP mode
  jtag2pdi         = Atmel JTAG ICE mkII PDI mode
  jtag2slow        = Atmel JTAG ICE mkII
  jtag3            = Atmel AVR JTAGICE3 in JTAG mode
  jtag3dw          = Atmel AVR JTAGICE3 in debugWIRE mode
  jtag3isp         = Atmel AVR JTAGICE3 in ISP mode
  jtag3pdi         = Atmel AVR JTAGICE3 in PDI mode
  jtagkey          = Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2
  jtagmkI          = Atmel JTAG ICE (mkI)
  jtagmkII         = Atmel JTAG ICE mkII
  jtagmkII_avr32   = Atmel JTAG ICE mkII im AVR32 mode
  o-link           = O-Link, OpenJTAG from www.100ask.net (avrdude: Error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.)
  xil              = Xilinx JTAG cable (tested - avrdude: can't claim device "/dev/ttyACM0": Inappropriate ioctl for device)
  xplainedpro      = Atmel AVR XplainedPro in JTAG mode

Den nachfolgenden Befehl nutze ich zum Test, ob der jeweilige Programmer-Typ funktioniert, er sollte bei erfolgreicher Kommunikation nur Backups von fuses anlegen, also führt noch keine schreibenden Operationen aus:

user@host:~/work/JTAGduino$ PATH=$PATH:/arduino-1.8.1/hardware/tools/avr/bin avrdude -p m169 -c xil -P /dev/ttyACM0 -C /arduino-1.8.1/hardware/tools/avr/etc/avrdude.conf -U lfuse:r:backup/unknown/`date  "+%F_%T"`/lfuse.hex:h -U hfuse:r:backup/unknown/`date  "+%F_%T"`/hfuse.hex:h -U efuse:r:backup/unknown/`date  "+%F_%T"`/efuse.hex:h

So wie es aussieht, ist die Library nicht komplett, und für meinen Anwendungszweck vielleicht gar nicht geeignet. Ich bin dadurch über eine JTAG-Library gestoßen, welche man direkt über die Arduino-IDE nachinstallieren kann: https://github.com/mrjimenez/JTAG

Nach dem Upload des JTAGTest-Programms (wird als Beispiel in der ArduinoIDE bereitgestellt, wenn man die Bibliothek installiert hat) auf dem Arduino kann man das python-Programm „xsvf“ nutzen, um erste Tests durchzuführen:

user@host:~/work/JTAG/extras/python$ ./xsvf ../xsvf/all/idcode_simpler.xsvf
File: /work/JTAG/extras/xsvf/all/idcode_simpler.xsvf
Ready to send 18 bytes.
Sent:       18 bytes,        0 remaining
IMPORTANT: ********
IMPORTANT: Success!
IMPORTANT: ********
IMPORTANT: Last TDO: FF FF FF FF/32 bits
IMPORTANT: Processed 5 instructions.
IMPORTANT: Checksum:  0xC2/18.
IMPORTANT: Sum: 0x0000003E/18.
Quit: No error (0).
  Expected checksum:  0xC2/18.
  Expected sum: 0x0000003E/18.
Elapsed time: 0.02 seconds.

Mit der neuen JTAG-Library alle möglichen Programmiermodi des avrdude durchgegangen:

atmelice         = Atmel-ICE (ARM/AVR) in JTAG mode (avrdude: jtag3_open_common(): JTAGICE3/EDBG port names must start with "usb")
  dragon_jtag      = Atmel AVR Dragon in JTAG mode (no response)
  jtag1            = Atmel JTAG ICE (mkI) (avrdude: jtagmkI_open(): failed to synchronize to ICE)
  jtag1slow        = Atmel JTAG ICE (mkI) (avrdude: jtagmkI_open(): failed to synchronize to ICE)
  jtag2            = Atmel JTAG ICE mkII (no response)
  jtag2avr32       = Atmel JTAG ICE mkII im AVR32 mode (avrdude: jtagmkII_recv_frame(): timeout     avrdude: jtagmkII_getsync(): sign-on command: status -1)
  jtag2dw          = Atmel JTAG ICE mkII in debugWire mode
  jtag2fast        = Atmel JTAG ICE mkII
  jtag2isp         = Atmel JTAG ICE mkII in ISP mode
  jtag2pdi         = Atmel JTAG ICE mkII PDI mode
  jtag2slow        = Atmel JTAG ICE mkII
  jtag3            = Atmel AVR JTAGICE3 in JTAG mode
  jtag3dw          = Atmel AVR JTAGICE3 in debugWIRE mode
  jtag3isp         = Atmel AVR JTAGICE3 in ISP mode
  jtag3pdi         = Atmel AVR JTAGICE3 in PDI mode
  jtagkey          = Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2
  jtagmkI          = Atmel JTAG ICE (mkI)
  jtagmkII         = Atmel JTAG ICE mkII
  jtagmkII_avr32   = Atmel JTAG ICE mkII im AVR32 mode
  o-link           = O-Link, OpenJTAG from www.100ask.net (avrdude: Error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.)
  xil              = Xilinx JTAG cable (avrdude: can't claim device "/dev/ttyACM0": Inappropriate ioctl for device)
  xplainedpro      = Atmel AVR XplainedPro in JTAG mode (avrdude: jtag3_open_common(): JTAGICE3/EDBG port names must start with "usb")

 

Arduino als Audio-Aufnahmequelle

Ich habe einen der Mikrofon-Sensoren ergattert, die man für Arduino bzw. Raspberry Pis günstig erwerben kann. Meiner war in einem „37 in 1“-Sensor-Kit enthalten. Schließt man diesen direkt mit A0 an den Arduino an, erhält man allerdings keine sinnvollen Werte, insbesondere weichen diese kaum von 2.5V Eingang ab. Die prinzipielle Schaltung lässt aber auf „D0“ das High bzw. Low erkennen, der Sensor selbst funktioniert also.

Um sinnvoll damit arbeiten zu können, musste ich zunächst einmal den Ausgang entkoppeln, dafür habe ich einen kleinen Kondensator (4.7 uF) angeschlossen. Das aus dem A0-Anschluss dieses Mikrofon-Breakouts erhaltene Signal ist nur zu schwach, muss also deutlich verstärkt werden. Ich habe einen MAX406 gefunden, der herumlag. Mit 470 Ohm als Vorwiderstand und 100 kOhm als Widerstand zwischen IN- und OUT sollte eine etwa 25-fache-Verstärkung herauskommen.

Das Signal aus dem Mikrofon komm ebenfalls an IN-, an IN+ habe ich GND angeschlossen.

Mit einem Piezo-Lautsprecher angeschlossen an GND und PIN9 vom Arduino Uno und das verstärkte Eingangssignal an A0 kann man nun gute das „Knackern“ hören, was vorher nur ein unangenehmes Piepsen war. Im seriellen Output kann man gut nachvollziehen, dass von der Schwallwelle nur eine Seite der Welle verstärkt wird, die andere ist praktisch immer Null und somit kommt auch noch nicht wirklich etwas verständliches heraus. Immerhin sind einfach Testtöne (Sinus-Wellen) darüber schon zu erkennen.

Ein möglicher nächster Schritt wäre nun:

Über einen (einstellbaren) Spannungsteiler die Referenzspannung, die an IN+ gegeben wird, zu verkleinern. Ferner muss das Eingangssignal durch einen 1:1-Spannungsteiler geschickt werden, um dann bei „keinem“ Signal etwa 50% Ausgangssignal zu liefern und dies dann beim Arduino wieder herauszurechnen. So würde das Signal vollständig verstärkt werden.

WinPCap in eigenem .NET-Programm verwenden

Den letzten „Developer’s Pack“ von WinPCap herunterladen:

http://www.winpcap.org/devel.htm

Auspacken und die Location merken, wo die Dateien nun liegen.

Wrapper herunterladen:

https://github.com/PcapDotNet/Pcap.Net/tree/master

Am einfachsten hierzu das aktuelle Repository als ZIP-Datei herunterladen und entpacken:

https://github.com/PcapDotNet/Pcap.Net/archive/master.zip

In dem ausgepackten Pfad diese Solution öffnen:

Pcap.Net-master\PcapDotNet\src\PcapDotNet.sln

  • Auf „Release“ umstellen
  • Auf „x64“ umstellen
  • PcapDotNet.Core -> Rechtsklick -> Eigenschaften
    • VC++ Directories
      • Include Directories: Den Pfad vom WpdPack\Include hinzufügen
      • Library Directories: Den Pfad von WpdPack\Lib\x64 hinzufügen
  • Alles kompilieren (Das Target Framework muss identisch mit dem im nächsten Schritt verwendeten sein)

Testweise etwas kompilieren:

Pcap.Net-master\PcapDotNet.DevelopersPack\src\PcapDotNet.DevelopersPack.sln öffnen

Bei „ObtainingTheDeviceList“ muss man die References anpassen, die Pfade müssen auf die „Relase“-Zweige der oben erstellten DLLs zeigen.

Das Resultat sollte ein Kommandozeilenfenster mit „1. rpcap://\Device…“ sein.

Export EV3 from Lego Digital Designer

Recently I created a complex LEGO model with Lego Digital Designer and wanted to import the resulting model into Blender. My export files were missing the LEGO Mindstorms EV3-components that I had added.

The reason for this behaviour are the missing parts in the ldraw.xml-File, which is in the same directory as the ldd.exe, the directory C:\Program Files (x86)\LEGO Company\LEGO Digital Designer held this file for me.

The ldraw.xml is essentially a mapping file, which maps all the LEGO-internal structures to the more open „LDRAW“-File format. The EV3-parts weren’t listed and even in updated ldraw.xml-Files, which I could find on the web, these were never added.

So I created the missing mappings on my own and the result works pretty good. Not all the colours are correct, but I couldn’t find an easy way to correct these.

Here are the necessary steps to successfully export LEGO EV3-parts from Lego Digital Designer and import these with correct colours e.g. into Blender:

  1. Copy ldraw.xml file to your location of ldd.exe, overwrite the old ldraw.xml. (Unzip the ldraw.zip to ldraw.xml first)
  2. Export your model from Lego Digital Designer to „LDraw-Files (*.ldr)“-format.
  3. Open the file in notepad++, search for the following part numbers (they are located at the end of the line) and change the BEGINNING of the line from „1 71“ to „1 15“.
    • Example:
      • 1 71 -90.175277709960937 -176.40634155273437 -275.99981689453125 0 1.0000001192092896 0 0 0 1.0000001192092896 1.0000001192092896 0 0 95658.dat
      • 1 15 -90.175277709960937 -176.40634155273437 -275.99981689453125 0 1.0000001192092896 0 0 0 1.0000001192092896 1.0000001192092896 0 0 95658.dat
    • Do this for all lines with these part numbers (not all might be in your file, only if you have added the corresponding EV3-bricks):
      • 95650.DAT
      • 95658.DAT
      • 95648.DAT
      • 99455.DAT
  4. Import the corrected file in LeoCAD and export into „Wavefront (.obj)“
  5. Open Blender and follow these instructions to get a first decent result:
    1. File -> Import -> Wavefront (.obj)
    2. Select -> Select all by Type -> Mesh
    3. Press „s“ (SCALE) and enter a value (blind, there is no dialog box), e.g. „0.1“ and hit return. Or you resize with your mouse after pressing „s“.
    4. Right-click and hold on the camera in blender, and move it around to where you want it to be.
    5. Check your current view by hitting the „0“ on your numpad. (This will change to the camera view)
    6. Right-Click during camera view on the border of the camera (it will turn orange), and then right-click and hold outside the camera view to tilt for your needs.
    7. Add some lights via Add -> Lamp -> Area  (or Sun) and position them.
    8. Render by pressing F12
    9. In the render-menu on the right hand side you can change the size of the resulting image, e.g. „Preset: HDTV 1080p“.
    10. By pressing F3 the rendered image is stored to your disc. (Current used path is at the bottom of the render-menu, defaults to /tmp.)

KODI: Spinup HDD when Screensaver was deactivated

When trying to access my recordings on my NAS, kodi seems to stop working for a short while when the NAS realizes that it is being accessed and starts spinning up the discs. I figured that it would be nice for the NAS to spin up earlier, if the screen saver of a „connected KODI“ is deactivated.

After enabling the JSON-RPC-TCP 9090-Port on Kodi (In System/Settings/Network/Services activate „Allow programs on this system to control Kodi for localhost access only“ and „Allow programs on other systems to control Kodi for access from other computers as well“), this script should be run at boottime on the NAS. Make sure to replace the accessed discs with your /dev/sdX-entries on your system. Also replace HOSTNAME with the host which as Kodi running, if the discs are in use on the same host, replace it with „localhost“.

The command must be run as root.

onidlespinupdiscs.sh:

#!/bin/bash
# Must be run as root
while true
do
  netcat -d HOSTNAME 9090 | (
    cnt=0
    line=
    while read -N 1 c; do
      line="$line$c"
      if [ "$c" = "{" ]; then
        cnt=$((cnt+1))
      elif [ "$c" = "}" ]; then
        cnt=$((cnt-1))
        if [ $cnt -eq 0 ]; then
          printf "%s\n" "$line"
          line=
        fi
      fi
    done
  ) | while read line
  do
    match=$(echo ${line} | grep -c "GUI.OnScreensaverDeactivated")
    if [ $match -eq 1 ]; then
      dd if=/dev/sdb bs=4096 count=1 of=/dev/null iflag=direct >/dev/null 2>&1 &
      dd if=/dev/sdc bs=4096 count=1 of=/dev/null iflag=direct >/dev/null 2>&1 &
    fi
  done
  sleep 60
done

Disable all LEDs and network LEDs on Raspberry Pi 2 with OpenELEC

I’m using OpenELEC on a Raspberry Pi 2, but the LEDs, especially those of the network device, are WAY too bright and keep distracting people when watching TV. The LEDs which are onboard of the RPi2 can be disabled with two simple commands (see below), but the network lights are much brighter and can’t be disabled by default.

I found a website which was written in portoguese, which offered a patch for this problem. The patch didn’t work with the current OpenELEC-release, so I had to modify it a bit.

Simply put, the patch adds a new functionality to the driver for the network interface smsc95xx.c, by creating three sysfs-entries.

Here is the modified patch, to apply it, you have to git clone the current OpenELEC-github-Repository and copy the patch to this directory: /OpenELEC.tv/packages/linux/patches/

File linux-999-disable-network-lights.patch:

--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -74,6 +74,8 @@
 module_param(turbo_mode, bool, 0644);
 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
 
+int smsc95xx_ledctl(struct usbnet *dev);
+
 static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
                                            u32 *data, int in_pm)
 {
@@ -1024,6 +1026,9 @@
        if (ret < 0)
                return ret;
 
+       // Init sysfs led controller
+       smsc95xx_ledctl(dev);
+
        /* Init Tx */
        ret = smsc95xx_write_reg(dev, FLOW, 0);
        if (ret < 0)
@@ -2023,3 +2028,87 @@
 MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>");
 MODULE_DESCRIPTION("SMSC95XX USB 2.0 Ethernet Devices");
 MODULE_LICENSE("GPL");
+
+/*
+ * Led control patch
+ */
+
+static struct usbnet *leddev = NULL;
+
+static ssize_t smsc95xx_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count);
+static ssize_t smsc95xx_show(struct class *cls, struct class_attribute *attr, char *buf);
+
+static CLASS_ATTR(eth_fdx,S_IWUSR, smsc95xx_show, smsc95xx_store);
+static CLASS_ATTR(eth_lnk,S_IWUSR, smsc95xx_show, smsc95xx_store);
+static CLASS_ATTR(eth_spd,S_IWUSR, smsc95xx_show, smsc95xx_store);
+
+int smsc95xx_ledctl(struct usbnet *dev){
+
+    int ret = 0;
+    static struct class led_gpio = {
+
+        .name = "smsc95xx_leds",
+    };
+
+    if(leddev != NULL) return 0;
+
+    leddev = dev;
+
+    ret = class_register(&led_gpio);
+    if(ret){
+        leddev = NULL;
+        return ret;
+    }
+
+    ret += class_create_file(&led_gpio,&class_attr_eth_fdx);
+    ret += class_create_file(&led_gpio,&class_attr_eth_lnk);
+    ret += class_create_file(&led_gpio,&class_attr_eth_spd);
+
+    if(ret){
+        leddev = NULL;
+        class_unregister(&led_gpio);
+        return ret;
+    }
+
+    return 0;
+}
+
+static ssize_t smsc95xx_show(struct class *cls, struct class_attribute *attr, char *buf){
+
+return scnprintf(buf, PAGE_SIZE, "you can't even read");
+}
+
+
+static ssize_t smsc95xx_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count){
+int ret = 0;
+static u32 write_buf = LED_GPIO_CFG_FDX_LED |
+                       LED_GPIO_CFG_LNK_LED |
+                       LED_GPIO_CFG_SPD_LED;
+
+
+    if(buf[0] == '0'){
+
+        switch(attr->attr.name[6]){
+
+            case 'x': write_buf ^= LED_GPIO_CFG_FDX_LED; break;
+            case 'k': write_buf ^= LED_GPIO_CFG_LNK_LED; break;
+            case 'd': write_buf ^= LED_GPIO_CFG_SPD_LED; break;
+        }
+
+    }else if(buf[0] == '1'){
+
+        switch(attr->attr.name[6]){
+
+            case 'x': write_buf |= LED_GPIO_CFG_FDX_LED; break;
+            case 'k': write_buf |= LED_GPIO_CFG_LNK_LED; break;
+            case 'd': write_buf |= LED_GPIO_CFG_SPD_LED; break;
+        }
+    }
+
+    ret = smsc95xx_write_reg(leddev, LED_GPIO_CFG, write_buf);
+
+    if(ret < 0) netdev_warn(leddev->net,"Failed to write LED_GPIO_CFG: %d\n",ret);
+
+    return 1;
+}
+

If the file is correctly copied, you can start to build the image, this will take some time:

PROJECT=RPi2 ARCH=arm make image

Copy the new image to a fresh sd-card and insert it into the RPi2. After boot, connect to ssh (you have to enable the sshd via the on-screen menu which you will see at the beginning) and add a new file, called autostart.sh to the ~/.config/ directory:

autostart.sh

#!/bin/bash
 
# Turn off system LEDs
echo none > /sys/class/leds/led0/trigger
echo 0 > /sys/class/leds/led0/brightness
 
echo none > /sys/class/leds/led1/trigger
echo 0 > /sys/class/leds/led1/brightness
 
# Turn of network LEDs
echo 0 > /sys/class/smsc95xx_leds/eth_fdx
echo 0 > /sys/class/smsc95xx_leds/eth_lnk
echo 0 > /sys/class/smsc95xx_leds/eth_spd

UPDATE:

As I wanted to keep my existing configuration and the IR-support, I wanted to compile the Openelec-Branch for the 7.0 version.

git clone https://github.com/OpenELEC/OpenELEC.tv.git
cd OpenELEC.tv
git checkout openelec-7.0
cp ../linux-999-disable-network-lights.patch packages/linux/patches/4.4.45/
PROJECT=RPi2 ARCH=arm make image

Minimal-Arduino selbst bauen: Bootloader auf ATMEGA328P-PU

Zunächst einmal braucht man für die Programmierung der ATMEGA328P-PU einen „normalen“ Arduino. Ich habe mir bei ebay für wenig Geld aus Hong Kong einen Arduino-Klon besorgt. Es handelte sich dabei um einen „Pro.mini.328P“ („New Pro Mini atmega328 Board 5V 16M Arduino Compatible Nano NEW“). Das Gerät war ohne USB-Header ausgestattet, also musste ich zunächst noch einen USB-Serial-Wandler hierfür nutzen. Diesen hatte ich schon, er stammte ebenfalls aus Hong Kong.

Nachdem RX vom USB-Wandler zum TX vom mini Pro verbunden wurden, musste noch TX<->RX, 5V<->VCC und GND<->GND verbunden werden. Die „Blink“-Demo sollte laufen.

Danach die Blink-Demo in der Arduino-Programmierumgebung laden und testweise auf den Ardunio laden. Blinkt die Diode nun im (neu) vorgegebenen Takt, hat alles geklappt. Die Voraussetzung für die eigentliche Programmierung ist jetzt gegeben.

Nun kann man sich grob weiter an dem Artikel der make-Redaktion entlanghangeln: http://www.heise.de/make/artikel/Arduino-Uno-als-In-System-Programmer-2769246.html

Übrigens: Um das AVRDUDE unter Windows zu nutzen, lädt man sich das Open Source-Programm von hier: http://download.savannah.gnu.org/releases/avrdude/avrdude-6.1-mingw32.zip

Als nächsten Schritt muss der Pro.mini.328P zu einem ISP-Programmer gemacht werden. Hierzu lädt man in der Arduino-IDE unter „Beispiele“ den Sketch „Ardunio ISP“ aus und lädt diesen hoch.

Die Verkabelung muss danach wie folgt aussehen (den 10kOhm-Widerstand am Pin 1 kann man auch weglassen).

BreadboardAVR

Der Quarz muss wirklich gut verbunden sein, sonst erhält man fortlaufend nur Fehlermeldungen der Art:

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x36
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x36

Und man sollte beim als ISP verwendeten Arduino nicht vergessen, zwischen GND und RESET einen 10 Micro-Farad-Kondensator einzusetzen, da dieser sonst immer wieder zurückgesetzt wird.

In der Arduino-IDE den ZIEL-Arduino auswählen (Hier: ATMEGA328P-PU = Arduino Uno) und als Programmer auf „ArduinoISP“ umstellen. Dann kann man mit „Bootloader brennen“ hoffentlich das blinken des Arduinos sehen und nach wenigen Sekunden ist der Bootloader fertig gebrannt. Da ich hiernach eine Menge unnötiger Zeit mit einer Fehlersuche vertan hatte, hier noch der wichtige Tipp, dass man den Quell-Arduino (den man als ISP einsetzt) am Ende, also nach fertigem Brennen noch einmal in den RESET schickt. Aus irgendeinem Grund hatte bei mir der ATMEGA328P sonst in einer Breadboard-Anordnung keinerlei Anstalten gemacht, das Bootloader-Blinken zu Beginn von sich zu geben, noch irgendein Programm via RX/TX anzunehmen.

Noch ungelöstes Problem: Nur nach einem manuellen (!) Reset akzeptiert der ATMEGA328P ein neues Programm aus der Arduino-IDE via RX/TX.

Low Power Arduino ATMEGA328P

Nachdem ich den Minimal-Arduino auf dem Breadboard aufgebaut hatte, wollte ich diesen gerne über eine CR2032-Batterie mit Strom versorgen, und das möglichst lange.

Zum Glück gibt es schon einige Artikel im Internet, die sich mit dem Stromverbrauch des ATMEGA328P auseinandergesetzt haben. Allerdings erwarten hier viele einen Interrupt von Extern, was in meinem Anwendungsfall (halbwegs regelmässig einen Sensor auslesen und die Information abspeichern oder verschicken) nicht ganz praktisch war. Vor allem, weil ich den passenden Uhrenquarz nicht verfügbar habe…

Hier also (nachvollziehbar) die einzelnen Schritte, die ich bei meinem ATMEGA328P unternommen habe, um ihn den hohen Stromverbrauch streitig zu machen.

Step 1: Default blink program with 5s delay, 16 MHz ext. Osz., 3V CR2032-battery

void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}
 
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(5000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(5000);              // wait for a second
}

Result:

  • LED On: 6.8mA
  • LED Off: 5.8mA

Step 2: All other pins as input

void setup() {
  //To reduce power, setup all pins as inputs with no pullups
  for(int x = 1 ; x < 18 ; x++){
    pinMode(x, INPUT);
    digitalWrite(x, LOW);
  }
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}
 
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(5000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(5000);              // wait for a second
}

Result:

  • LED On: 6.45mA
  • LED Off: 5.65mA

Step 3: Power Down during sleep

I’ll admit that this next step is a bit confusing, as a lot of things are introduced.

#include <avr/sleep.h> //Needed for sleep_mode
#include <avr/wdt.h>
 
volatile boolean f_wdt=1;
 
void setup() {
  //To reduce power, setup all pins as inputs with no pullups
  for(int x = 1 ; x < 18 ; x++){
    pinMode(x, INPUT);
    digitalWrite(x, LOW);
  }
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  setup_watchdog(8);
}
 
byte state=0;
 
void loop() {
    if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag
    switch (state){
    case 0:
      digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
      state = 1;
      setup_watchdog(0);
      break;
    case 1:
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      state = 0;
      setup_watchdog(8);
      break;
    }
    system_sleep();
  }
}
 
//****************************************************************  
// set system into the sleep state 
// system wakes up when watchdog is timed out
void system_sleep() {
  // power_adc_disable()
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
  sleep_mode();                        // System sleeps here
  sleep_disable();                     // System continues execution here when watchdog timed out 
  // power_adc_enable()
}
 
//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
 
  byte bb;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
 
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}
//****************************************************************  
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}

Result:

  • LED On: 1.07mA
  • LED Off: 0.02mA (206uA)

As long as we depend on the internal oscillator, we won’t get any further then 206uA, as the watchdog is still enabled and drawing current. Time to get one of those nice 32kHz-oscillators.

Here are some more links related to this topic, some of those helped me in my process (some in german):

  • http://www.mikrocontroller.net/articles/Sleep_Mode
  • http://interface.khm.de/index.php/lab/interfaces-advanced/sleep_watchdog_battery/

Android App entwickeln: Erste Schritte

Abrufbare Sensoren Auflisten

Im verwendeten „Blank Activity“ ist bereits ein Textfeld enthalten, welches derzeit nur ein „Hello world!“ von sich gibt. Dieses wollen wir erstmal als Ausgabefeld für unsere ersten Tests behalten.

Zunächst möchte ich wissen, welche Sensoren in dem verwendeten Android-Gerät enthalten sind. Hierzu fügt man zunächst die folgende Prozedur in „MainActivity“ hinzu:

public void listSensors()  {
    // Find the text view
    TextView  t;
    t=(TextView)findViewById(R.id.textView);
    t.setText("");
 
    // Init SensorManager
    SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    // Get the list of sensors
    List listSensor = sensorManager.getSensorList(Sensor.TYPE_ALL);
    List listSensorType = new ArrayList();
    // Append all sensor names to the text view
    for(int i=0; i<listSensor.size(); i++){
        listSensorType.add(listSensor.get(i).getName());
        t.append(listSensor.get(i).getName());
        t.append("\n");
    }
}

Die IDE wird einige Begriff in ROT kennzeichnen, weil wir die notwendigen Imports nicht durchgeführt haben. Das lässt sich aber sehr bequem erledigen. Maus auf eines der roten Wörter positionieren und Alt+Eingabe drücken.

Zum Schluss beschwert sich die IDE noch darüber, dass „R.id.textView“ nicht gefunden werden kann. Dazu wechselt man in die activity_main.xml, wählt das „textView“-Element aus und vergibt in den Properties unter „id“ den Namen „textView“.

Nun müssen wir die Prozedur listSensors() nur noch im onCreate() aufrufen und schon werden beim Start der App alle Sensoren aufgelistet.