Friday, June 21, 2019

Garmin Lidar Lite V3 on OrangePi PC

Connect Garmin Lidar Lite V3 to the OrangePi PC 40-pin header, either on I2C-0,

 3  
twi0_sda 
blue

 4
+5V        
red
 5 
twi0_sck
green

 6
gnd
black

or I2C-1,

27 
twi1_sda 
blue

28
twi1_sck 
green

Run i2c detection on bus 0:  i2cdetect 0; and the device is detected on 0x62, the default address.

Start by trying a Python version that uses smbus (or smbus2).  But all registers read 0.

Try Garmin's LIDARLite_RaspberryPi_Library.  Note that the library hard coded the i2c bus to i2c-1.  The code compiles and runs fine without modification.  Add code to do a register dump,
0x00
0x05
ACQ_COMMAND
0x01
0x26
STATUS
0x02
0x80
SIG_COUNT_VAL
0x04
0x08
ACQ_CONFIG_REG
0x09
0x67
VELOCITY
0x0c
0xe8
PEAK_CORR
0x0d
0x3d
NOISE_PEAK
0x0e
0x9a
SIGNAL_STRENGTH
0x0f
0x00
FULL_DELAY_HIGH
0x10
0x9e
FULL_DELAY_LOW
0x11
0x01
OUTER_LOOP_COUNT
0x12
0x05
REF_COUNT_VAL
0x14
0x00
LAST_DELAY_HIGH
0x15
0x05
LAST_DELAY_LOW
0x16
0x34
UNIT_ID_HIGH
0x17
0x30
UNIT_ID_LOW
0x18
0x00
I2C_ID_HIGH
0x19
0x00
I2C_ID_LOW
0x1a
0x00
I2C_SEC_ADDR
0x1c
0x00
THRESHOLD_BYPASS
0x1e
0x00
I2C_CONFIG
0x40
0x00
COMMAND
0x45
0x14
MEASURE_DELAY
0x4c
0x43
PEAK_BCK
0x52
0x00
CORR_DATA
0x53
0x00
CORR_DATA_SIGN
0x5d
0x00
ACQ_SETTINGS
0x65
0x00
POWER_CONTROL
Add 0.5 sec delay.  It prints distance at about 1 Hz.  The max update rate appears to be 300Hz , possibly limited by 100KHz I2C speed.  Occasionally, there are errors and the kernel prints error message,
sunxi_i2c_do_xfer()985 - [i2c1] incomplete xfer (status: 0x48, dev addr: 0x62)
 This is using armbian 5.38 with linux image sun8i 3.4.113.

Try to display the distance on the 1.8" LCD.   The simplest way is just to redirect the fb console.  Use con2fbmap to map a tty console to the fb.  And to set to a large font,
sudo setfont -C /dev/tty1 /usr/share/consolefonts/Lat15-TerminusBold14.psf.gz 
 For something fancier, need a graphics library.  The SDL library can be used.  Python Pygame can be set to use SDL to test it out.  Pygame works fine on the LCD.  It is very desirable to stay with Python.  So SWIG is used to add python interface to the Garmin library.  With that, the LCD displays the distance nicely.  However, there are some unresolved issues with console/framebuffer management.  The other option is just to write to the framebuffer directly as images.  Note that the format is hardware dependent; for this particular LCD, the format is packed 16-bit RGB (5/6/5).

Wednesday, May 29, 2019

FreeDOS on AtomicPi

Atomic Pi can be a great platform to try other OSes, such as DOS, ReactOS, Minix.  Here we start with the oldest PC OS, DOS.  We will install FreeDOS to a microSD card.  We will use an old 256MB microSD card.

It appears that the easiest way to get a DOS disk image is to use VirtualBox, QEMU or Bochs.  We get the CDROM ISO file from freedos.org.  We'll use QEMU.  First, create a 200MB DOS disk,
qemu-img create dos.img 200M
Then run the emulator to boot from the ISO image,
 qemu-system-i386 -m 16 -k en-us -rtc base=localtime  -hda dos.img -cdrom FD12CD.iso -boot order=d
We proceed with installation.  We did a full installation, which took about 89MB.  Additionally packages can be installed by running fdimples.  Included on the CD are games, including a version DOOM clone, BOOM, which runs fine on QEMU.

We can mount the disk image in Linux,
 sudo mount -o loop,offset=32256 dos.img /mnt/dos/
The offset is necessary, because the DOS partition starts at sector 63.  We can write the disk image to the SD card
 dd if=/dev/loop0 of=/dev/sdb1
We install the DOS MBR by adding it as the second disk,
 qemu-system-i386 -hda dos.img -hdb /dev/sdb
and run `fdsik /mbr 2`.
After that, we can directly boot the SD card,
 qemu-system-i386 -hda /dev/sdb 
On an older PC with Intel Core2 Duo,  it boots directly with a USB uSD reader.  Or we can use GRUB chain-loading,
set root=(hd1,msdos1)
chainloader +1
boot
We added this as another menuentry to the grub.cfg file.

However, if we try chain-loading on Atomic Pi, we get the error message "invalid EFI file path".  The Atomic Pi BIOS cannot load the legacy MBR; and it may not provide the BIOS that DOS is depended on.  It does not seem to have the Compatibility Support Module to provide the legacy BIOS support.

Is it possible to have a BIOS compatibility layer?




Wednesday, May 8, 2019

Atomic Pi

At some point, there is bound to be a version of Pi with an Intel processor.  Atomic Pi is here for a similar price of $35.   It comes with Atom x5-Z8350, 2GB RAM, 16GB flash.  x5-Z8350 has a max TDP of 4W; with a large heat sink, it can run fanless.  (Compared with a similar performance Core 2 Duo T7200 of 34W max TDP.)  There is one USB 3 port; another USB 2 port does not has standard USB A connector.  A 26-pin I/O header has 2 UARTs and 6 GPIOs.  The audio circuitry is a little curious: a digital audio power amplifier and a microcontroller for two digital microphones.  For most part it appears superior to Raspberry Pi.

The board is about 260g.  It lacks a convenient power connector.  So the first thing is to solder a more standard 2mm power jack.
We need to connect a keyboard/mouse to the USB and a monitor to the HDMI connector.   Power up and we see the BIOS screen then the Lubuntu login screen.  The current draw is about 1.2A and does not seem to exceed 1.5A.  The board draws 0.1A after shutdown.  In the suspend mode, the board draws 0.4A.  We also need to attach antennas for WiFi and Bluetooth; both work fine.  At the BIOS splash screen, DEL key gets into the BIOS settings.  We set the date and time, which is back with CR2032 coin battery.

The preinstalled OS distribution is Ubuntu 18.04.1 LTS.   The python script for BNO055 (gyro, accel and mag) works. Run stress to load the CPU; the temperature only gets up to 55C (from 44C idle) with current draw about 1.6A.   The heatsink is only a little warm.  The video playing at the full screen is smooth.  Initially there is no audio through HDMI and the problem is solved by changing pulseaudio configuration (using instructions from the user forum).

I tried to boot from a uSD card, but it did not work.  It appears not to support legacy MBR boot.   We'll create UEFI boot partition and install efi bootloader,
grub-install --target=x86_64-efi --efi-directory=/mnt/ --bootloader-id=GRUB --boot-directory=/media/atomicpi/xxx/boot/ 
It was not able to find the config file initially; it was looking for it under ubuntu somehow.  So I put one there.  There is probably a way to specify it.  The uSD card had an Ubuntu 16.04 distribution, but it mostly worked here.  It did report some kernel driver issues and the HDMI audio driver did not load, apparently missing snd-hdmi-lpe-audio kernel module, which was not included in the 4.4.0 version of the kernel.  I upgraded the kernel to 4.15.0; now the audio driver was included.  But there seemed some problem starting pulseaudio.  In addition, a later version of gcc is required to compile the kernel module, i2c-gpio-custom.

We can also add the Linux system on the uSD to the default eMMC grub menu and boot into it.

The write speed to the uSD is 15.5MB/s and read speed is 29.1MB/s.

Run hardinfo benchmark; the results are: CPU Blowfish 6.60s, CPU CryptoHash 96.49MB/s, CPU Fibonacci 3.29s, CPU N-Queens 32.85s, FPU FFT 6.80s, FPU Raytracing 9.37s.  (Compared with Core 2 Duo Blowfish 10.7s, CryptoHash 155.50s, Fibonacci 4.86s, N-Queens 29.45s, FFT 4.46s, Raytracing 16.59s.)   According to PassMark CPU benchmarks, Z8350's average CPU mark is 1266 vs 1167 for T7200.

Next we'll test out the other connectors.

CN3 is the power button connector, unpopulated.  When the two pin shorted momentarily, it turns on the system or wakes up from suspend.

CN10 is the debug UART serial port (3.3V), /dev/ttyS0, which is the boot console, at 115,200 baud.  The AMI BIOS is also accessible here, so we do not have to connect a keyboard and a monitor, which is a great convenience.

Overall it is a very impressive board for the price.

Thursday, April 11, 2019

Fixing Power Adapter

I have an old AC power adapter that outputs 5V and 12V at 1A each with combined total output of 15W.  It stopped working.  I opened up and found the 2.5A input fuse was blown.   The primary side was shorted.   This offline power switcher seemed really simple.  There did not appear to have a controller IC; it was made entirely with discrete parts.  It did not take long to locate the faulty component, the primary side MOSFET switch, 2SK1535, a 900V 3A power MOSFET with 4-Ohm Rdson; all three pins were shorted.  It is a flyback switcher with two secondary outputs and an optocoupler off the 5V.





The first question is how it generates PWM signals.  Besides the main FET switch, the primary side has only one additional transistor. But the primary side has one auxiliary coil, which provides the positive feedback for oscillation.  The secondary side does not seem to even have a voltage reference, so how does it regulate?  There are only a transistor and a POT that feed the optocoupler.

After replacing the faulty MOSFET and the blown fuse, the switcher works again.  But one problem with the circuit is the lack of short-circuit protection.  The primary side switch can turn on hard and destroy itself before even the fuse blown. 


Monday, March 25, 2019

Alkaline Batteries

My Bluetooth mouse runs on two AA cells.  As the each battery drops below 1.2V, the mouse complains about low battery.  The alkaline battery does not completely drain until about 0.9V.  According to Energizer, its AA alkaline battery is about 3000mAh if discharged at 25mA (to 0.8V).   One of its diagrams shows that the battery has as much as 750mAh left at 1.2V, that is about 25%.

So how do we maximize the battery life?  The mouse draws relatively low current.  If we mix a fresh battery with a partially drained battery, that should have the voltage high enough.  A fresh alkaline battery has an internal resistance about 0.1 Ohm at the room temperature (rise to 0.4 Ohm at -20C) from the chart provided by Energizer.

I measured an alkaline battery with OCV 1.09V, when loaded with 10 Ohms, the voltage drops to 0.84V.  So the internal resistance about 2 Ohms at 84mA load.   For low current draw, it should still be able provide power.  With a fresh battery at 1.535V and a drained one at 0.992V, the mouse still works without any complaint.  The two batteries together are measured 2.47-2.51V when the mouse is on.  When the mouse finally start to complain about low battery, one battery has drained to about 0.83V and the other 1.47V.  We got about extra 4 weeks of battery life.



Tuesday, February 19, 2019

LCR-T4 Oscillator Upgrade

We will replace the 8MHz crystal with a 16MHz one on LCR-T4 transistor tester.  ATMega328p can run up to 20MHz.  The old firmware still seems to run with the 16MHz, but some measurements are off.  Maybe it can be fixed with calibration, but we'll just update the firmware.

The OP_MHZ parameter in the makefile defines the operating frequency of the CPU.  We change it to 16 from 8.  Now we can also enable crystal and ceramic resonator test by defining WITH_XTAL. Only 16MHz and 20MHz are supported for crystal test at this time.   F_CPU, F_CPU_HZ and MHZ_CPU are in turn defined by OP_MHZ. 

After compilation, the program size is shown to be 95.1% full, grown 2290 bytes.  The I2C display version no longer fit in the flash, exceeded by 216 bytes.
Program:   32984 bytes (100.7% Full)(.text + .data + .bootloader)
Data:        210 bytes (10.3% Full)(.data + .bss + .noinit)
EEPROM:      912 bytes (89.1% Full)(.eeprom)
So we disable the crystal test for now, and it is 93.5% full.   After programming the flash, it runs fine.

Now we'll try to trim the code a little so we can enable the crystal test.  Before doing any size optimization, we'll try to remove some features.  Looking the memory map, removing select_color() function would yield enough saving.  We change the compile option undef LCD_CHANGE_COLOR, which saves 586 bytes.  Now we have 370 bytes to spare.
Program:   32398 bytes (98.9% Full)
(.text + .data + .bootloader)
Data:        206 bytes (10.1% Full)
(.data + .bss + .noinit)
EEPROM:      887 bytes (86.6% Full)
(.eeprom)
We can test the XTAL function.  The crystal that we replaced is measured 8000.00KHz, not bad!  A 10MHz series resonance crystal is measured 9999.77kHz series and 10.0018MHz parallel.  But it seems that it cannot measure beyond 10MHz.

We further replace the crystal with a 20MHz one.  Now when we measure the 16MHz crystal, we get 15.9948MHz series, 15.9979MHz parallel.  However, other lower frequency crystals are measured incorrectly.  We'll look into it.


Tuesday, February 12, 2019

Garmin LIDAR Lite

We'll interface Garmin LIDAR Lite with esp32-pico-kit.  esp32-pico-kit interfaces the LIDAR using I2C.   We'll make use of the wireless connectivity.  First we'll transmit the data through Bluetooth.  And we'll the esp32-pico a webserver that'll display the data through WiFi.

The LIDAR runs on 5V, but itself I2C signal is 3.3V, which matches esp32.

We'll use Garmin's LIDARLite_Arduino_Library .  First, we'll try out the library example GetDistanceI2C.  It compiles and is uploaded without a problem.  After hooking up the I2C and 5V, the serial monitor spits out numbers.  For this, the Arduino serial plotter is a great tool to view the output.

Next we'll try to run esp32-pico-kit as a Bluetooth serial device.  We run the SerialToSerialBT example without a problem.  We have two way communications with a Bluetooth serial app on a smart phone.

Then we'll try an example of setting up a WiFi access point.  That also goes without a problem.

Now we have tested the major pieces and are ready to put them together.  We'll start with the LIDAR and BT serial.  That uses 72% of Flash and 12% RAM.  It works nicely .

We'll create a webserver to display the range data next.  We set the web page to auto refresh every second.   It uses 51% of Flash and 11% RAM.  It works just fine.  A lot of features can be added, such as displaying a live graph and changing registers etc.

The ease of create a working IoT system with arduino is quite amazing.