Orange Pi and Teensy Loader Work Together

I have installed RPI Linux Installer of Teensyduino on an RPI previously.

I simply took the teensy loader code and copied it from the RPI to the OPI, and tested it.

The testing was not extensive, but the software did run, so I expect I will be able to use the teensy loader to upgrade Teensies in the field with an OPI if necessary.

Posted in c-opi | Leave a comment

Orange Pi Setup / Use Issues

I followed my own ‘setup’ procedure with my new OPI. This includes building standard users, installing software I always use (FTP, SMTP, etc), and so on.

This gave me a chance to see what kind of issues I might have running Raspbian on OPI.

For the most part, I only saw a few problems. Unfortunately, they have all been somewhat nasty problems that took some time to resolve.

That being said, most everything works. As I was doing research, users were complaining bitterly about how unstable / unusable Raspian on OPI is. So far my opinion is nowhere near as negative. BUT I will also say this implementation of Raspian obviously doesn’t have the same kind of attention to detail that one would find on Raspberry Pi.

Here are the issues I have seen:

HDMI to DVI Converter

As mentioned in Orange PI One Installation, you really shouldn’t plan on using a DVI monitor. You might get it to work, you might not.

raspi-config Can’t Expand the File System

Everything I normally use raspi-config for (keyboard config, timezone, enable SSH) works EXCEPT it can’t expand the file system.

I did this by sticking the SD card into another system running linux and used gparted to resize the partition.

Can’t Use New Users

This was almost a show stopper: after creating my ‘standard’ users, I found I could not log into them. Well, I could login, but they would immediately exit / logoff.

This one took a few hours to track down. Not the kind of bug you would think would make it past QA. It’s been around a while and evidently it still isn’t fixed in the distribution.

This is corrected by tweaking the running configuration with:

echo "vm.mmap_min_addr = 4096" > /etc/sysctl.d/mmap_min_addr.conf

mmap_miin_addr.conf which will be executed each time the system is started.

VNC Install

This is more a warning than an error.

After installing VNC and trying to run tightvncserver for the first time I got an error regarding missing .Xauthority file and the server didn’t work correctly.

I restarted the service. This time there was no error, and it did work. Yay!

CPU(s) Shut Down Due to Heat

While trolling syslog, I discovered constant error messages regarding “CPU Budget: Temperature”.

I started looking around and others were complaining about this and about their CPU(s) being shutdown due to excessive heat.

Looking close in my log, sure enough, I found my CPU3 was being shutdown as well:

Sep 5 15:43:30 opi kernel: [ 4.920061] CPU Budget: Temperature: 73 Limit state:1 item[1200000,3,-1,0 0]
Sep 5 15:43:30 opi kernel: [ 4.920072] CPU Budget:Try to down cpu 3, cluster0 online 4, limit 3
Sep 5 15:43:30 opi kernel: [ 4.956805] CPU3: shutdown
Sep 5 15:43:30 opi kernel: [ 4.963550] [hotplug]: cpu(0) try to kill cpu(3)
Sep 5 15:43:30 opi kernel: [ 4.972376] [hotplug]: cpu3 is killed! .

Running top and using option ‘1’, sure enough, I only had 3 CPUs running.

I started researching this problem and found people talking about changing frequency, etc, etc. I was wary about making such changes. They also said you should be using a heatsink.

Well, I am using a heat sink so I checked the case and it seemed pretty warm to me.

I removed the OPI from the case and restarted it. So far no error messages in syslog.

This problem isn’t actually the fault of the OPI, but the case mfg whom didn’t do an adequate job of ventilation.

Sep 11, 2017 Update

I was given a copy of armbian to play with. It was much better setup to handle the Orange Pi, but the copy I had still had some issues, so I went over to Ambian and downloaded the latest version of Ubunutu Desktop for Armbian at .

This is much slicker than Raspian. I’d recommend it over Raspian for the most part. I’m not going to use it, at least for now, mainly because I have a ton of RPI’s running on Raspian right now and I want to keep everything consistent.

One big benefit of Armbian is it doesn’t experience the CPU shutdown issue due to over heating.

After pondering that difference, I decided the hardware is the hardware, there must be a difference in how Armbian is configured vs. Raspian.

I ended up copying bits and pieces of /boot/script.fex (aka script.bin) from Armbian to Raspian. Essentially, I now allow the CPU to get a little hotter, plus I think I am allowing the CPU frequency to drop either quicker or further (or maybe both).

Enclosed is the script.fex I’m using that no longer has the CPU shutdown issue. You will need to convert this to script.bin using the fex2bin tool.

USE AT YOUR OWN RISK. I just copied and pasted values I thought might help. There may be some weird side effect that causes the CPU to burst into flames. I don’t know – these changes are way outside the scope of my Linux knowledge!

version = "100"
machine = "Xunlong Orange Pi One"

debug_mode = 1
eraseflag = 1
next_work = 2

boot_clock = 1008
storage_type = -1

keyen_flag = 0

fel_key_max = 7
fel_key_min = 2

logical_start = 40960
sprite_work_delay = 500
sprite_err_delay = 200
sprite_gpio0 = port:PL10<1><default><default><default>
next_work = 3

used = 1
start_type = 1
irkey_used = 1
pmukey_used = 1
pmukey_num = 3
led_power = 0
led_state = 0

used = 1
gpio0 = port:PL10<1><default><default><1>
gpio1 = port:PG11<1><default><default><1>

used = 1
mode = 2
recovery_key = port:PL04<0><default><default><default>

standby_mode = 1

card_ctrl = 0
card_high_speed = 1
card_line = 4
sdc_d1 = port:PF00<2><1><2><default>
sdc_d0 = port:PF01<2><1><2><default>
sdc_clk = port:PF02<2><1><2><default>
sdc_cmd = port:PF03<2><1><2><default>
sdc_d3 = port:PF04<2><1><2><default>
sdc_d2 = port:PF05<2><1><2><default>

card_ctrl = 2
card_high_speed = 1
card_line = 8
sdc_cmd = port:PC06<3><1><2><default>
sdc_clk = port:PC05<3><1><2><default>
sdc_d0 = port:PC08<3><1><2><default>
sdc_d1 = port:PC09<3><1><2><default>
sdc_d2 = port:PC10<3><1><2><default>
sdc_d3 = port:PC11<3><1><2><default>
sdc_d4 = port:PC12<3><1><2><default>
sdc_d5 = port:PC13<3><1><2><default>
sdc_d6 = port:PC14<3><1><2><default>
sdc_d7 = port:PC15<3><1><2><default>
sdc_2xmode = 1
sdc_ddrmode = 1

twi_port = 0
twi_scl = port:PA11<2><default><default><default>
twi_sda = port:PA12<2><default><default><default>

uart_debug_port = 0
uart_debug_tx = port:PA04<2><1><default><default>
uart_debug_rx = port:PA05<2><1><default><default>

force_uart_port = 0
force_uart_tx = port:PF02<3><1><default><default>
force_uart_rx = port:PF04<3><1><default><default>

jtag_enable = 0
jtag_ms = port:PA00<3><default><default><default>
jtag_ck = port:PA01<3><default><default><default>
jtag_do = port:PA02<3><default><default><default>
jtag_di = port:PA03<3><default><default><default>

pll_video = 297
pll_ve = 402
pll_periph0 = 600
pll_gpu = 576
pll_periph1 = 600
pll_de = 864

dram_clk = 624
dram_type = 3
dram_zq = 0x3b3bfb
dram_odt_en = 1
dram_para1 = 283377664
dram_para2 = 0
dram_mr0 = 6208
dram_mr1 = 64
dram_mr2 = 24
dram_mr3 = 2
dram_tpr0 = 0x48a192
dram_tpr1 = 0x1c2418d
dram_tpr2 = 0x76051
dram_tpr3 = 0x0
dram_tpr4 = 0x0
dram_tpr5 = 0x0
dram_tpr6 = 0x64
dram_tpr7 = 0x0
dram_tpr8 = 0x0
dram_tpr9 = 0x0
dram_tpr10 = 0x0
dram_tpr11 = 0x6aaa0000
dram_tpr12 = 0x7979
dram_tpr13 = 0x800800

cpu_en = 0
cpu_freq = 48
pll_ratio = 273
dram_selfresh_en = 1
dram_freq = 36
wakeup_src0 =
wakeup_src_wl = port:PG10<4><default><default><0>
wakeup_src_bt = port:PL03<6><default><default><0>

twi_used = 1
twi_scl = port:PA11<2><default><default><default>
twi_sda = port:PA12<2><default><default><default>

twi_used = 1
twi_scl = port:PA18<3><default><default><default>
twi_sda = port:PA19<3><default><default><default>

twi_used = 0
twi_scl = port:PE12<3><default><default><default>
twi_sda = port:PE13<3><default><default><default>

uart_used = 1
uart_port = 0
uart_type = 2
uart_tx = port:PA04<2><1><default><default>
uart_rx = port:PA05<2><1><default><default>

uart_used = 0
uart_port = 1
uart_type = 4
uart_tx = port:PG06<2><1><default><default>
uart_rx = port:PG07<2><1><default><default>
uart_rts = port:PG08<2><1><default><default>
uart_cts = port:PG09<2><1><default><default>

uart_used = 0
uart_port = 2
uart_type = 4
uart_tx = port:PA00<2><1><default><default>
uart_rx = port:PA01<2><1><default><default>
uart_rts = port:PA02<2><1><default><default>
uart_cts = port:PA03<2><1><default><default>

uart_used = 0
uart_port = 3
uart_type = 4
uart_tx = port:PA13<3><1><default><default>
uart_rx = port:PA14<3><1><default><default>
uart_rts = port:PA15<3><1><default><default>
uart_cts = port:PA16<3><1><default><default>

spi_used = 1
spi_cs_bitmap = 1
spi_mosi = port:PC00<3><default><default><default>
spi_miso = port:PC01<3><default><default><default>
spi_sclk = port:PC02<3><default><default><default>
spi_cs0 = port:PC03<3><1><default><default>

spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PA13<2><1><default><default>
spi_sclk = port:PA14<2><default><default><default>
spi_mosi = port:PA15<2><default><default><default>
spi_miso = port:PA16<2><default><default><default>

spi_dev_num = 1

modalias = "spidev"
max_speed_hz = 33000000
bus_num = 0
chip_select = 0
mode = 0
full_duplex = 1
manual_cs = 0

gpio_used = 0
gpio_num = 0

leds_used = 1
green_led = port:PL10<1><default><default><1>
green_led_active_low = 0
red_led = port:PA15<1><default><default><0>
red_led_active_low = 0

ths_used = 1
ths_trip1_count = 6
ths_trip1_0 = 75
ths_trip1_1 = 80
ths_trip1_2 = 85
ths_trip1_3 = 90
ths_trip1_4 = 95
ths_trip1_5 = 105
ths_trip1_6 = 0
ths_trip1_7 = 0
ths_trip1_0_min = 0
ths_trip1_0_max = 1
ths_trip1_1_min = 1
ths_trip1_1_max = 2
ths_trip1_2_min = 2
ths_trip1_2_max = 3
ths_trip1_3_min = 3
ths_trip1_3_max = 4
ths_trip1_4_min = 4
ths_trip1_4_max = 5
ths_trip1_5_min = 5
ths_trip1_5_max = 7
ths_trip1_6_min = 0
ths_trip1_6_max = 0
ths_trip2_count = 1
ths_trip2_0 = 105

cooler_count = 8
cooler0 = "1200000 4 4294967295 0"
cooler1 = "912000 4 4294967295 0"
cooler2 = "768000 4 4294967295 0"
cooler3 = "648000 4 4294967295 0"
cooler4 = "480000 4 4294967295 0"
cooler5 = "480000 3 4294967295 0"
cooler6 = "480000 2 4294967295 0"
cooler7 = "480000 1 4294967295 0"

nand_support_2ch = 0
nand0_used = 0
nand0_we = port:PC00<2><default><default><default>
nand0_ale = port:PC01<2><default><default><default>
nand0_cle = port:PC02<2><default><default><default>
nand0_ce1 = port:PC03<2><default><default><default>
nand0_ce0 = port:PC04<2><default><default><default>
nand0_nre = port:PC05<2><default><default><default>
nand0_rb0 = port:PC06<2><default><default><default>
nand0_rb1 = port:PC07<2><default><default><default>
nand0_d0 = port:PC08<2><default><default><default>
nand0_d1 = port:PC09<2><default><default><default>
nand0_d2 = port:PC10<2><default><default><default>
nand0_d3 = port:PC11<2><default><default><default>
nand0_d4 = port:PC12<2><default><default><default>
nand0_d5 = port:PC13<2><default><default><default>
nand0_d6 = port:PC14<2><default><default><default>
nand0_d7 = port:PC15<2><default><default><default>
nand0_ndqs = port:PC16<2><default><default><default>

advert_disp = 0
auto_hpd = 1
output_type = 4
hdmi_channel = 0
hdmi_mode = 4
cvbs_channel = 1
cvbs_mode = 11
output_full = 1
hdmi_mode_check = 1

disp_init_enable = 1
disp_mode = 0
screen0_output_type = 3
screen0_output_mode = 10
screen1_output_type = 3
screen1_output_mode = 10
fb0_format = 0
fb0_width = 0
fb0_height = 0
fb1_format = 0
fb1_width = 0
fb1_height = 0
hdcp_enable = 0
hdmi_cts_compatibility = 1

hdmi_used = 1
hdmi_power = "vcc-hdmi-18"
hdcp_enable = 0
hdmi_cts_compatibility = 1

tv_used = 0
tv_dac_used = 1
tv_dac_src0 = 0

pwm_used = 0
pwm_positive = port:PA05<3><0><default><default>

gmac_used = 2
gmac_power1 =

vip_used = 1
vip_mode = 0
vip_dev_qty = 1
vip_define_sensor_list = 0
vip_csi_pck = port:PE00<2><default><default><default>
vip_csi_mck = port:PE01<2><default><default><default>
vip_csi_hsync = port:PE02<2><default><default><default>
vip_csi_vsync = port:PE03<2><default><default><default>
vip_csi_d0 = port:PE04<2><default><default><default>
vip_csi_d1 = port:PE05<2><default><default><default>
vip_csi_d2 = port:PE06<2><default><default><default>
vip_csi_d3 = port:PE07<2><default><default><default>
vip_csi_d4 = port:PE08<2><default><default><default>
vip_csi_d5 = port:PE09<2><default><default><default>
vip_csi_d6 = port:PE10<2><default><default><default>
vip_csi_d7 = port:PE11<2><default><default><default>
vip_csi_sck = port:PE12<2><default><default><default>
vip_csi_sda = port:PE13<2><default><default><default>
vip_dev0_mname = "gc2035"
vip_dev0_pos = "front"
vip_dev0_lane = 1
vip_dev0_twi_id = 2
vip_dev0_twi_addr = 120
vip_dev0_isp_used = 0
vip_dev0_fmt = 0
vip_dev0_stby_mode = 0
vip_dev0_vflip = 1
vip_dev0_hflip = 1
vip_dev0_iovdd = ""
vip_dev0_iovdd_vol = 2800000
vip_dev0_avdd = ""
vip_dev0_avdd_vol = 2800000
vip_dev0_dvdd = ""
vip_dev0_dvdd_vol = 1800000
vip_dev0_afvdd = ""
vip_dev0_afvdd_vol = 2800000
vip_dev0_power_en = port:PA17<1><default><default><1>
vip_dev0_reset = port:PE14<1><default><default><1>
vip_dev0_pwdn = port:PE15<1><default><default><0>
vip_dev0_flash_en =
vip_dev0_flash_mode =
vip_dev0_af_pwdn =
vip_dev0_act_used = 0
vip_dev0_act_name = "ad5820_act"
vip_dev0_act_slave = 24
vip_dev1_mname = ""
vip_dev1_pos = "rear"
vip_dev1_lane = 1
vip_dev1_twi_id = 0
vip_dev1_twi_addr =
vip_dev1_isp_used = 0
vip_dev1_fmt = 1
vip_dev1_stby_mode = 0
vip_dev1_vflip = 0
vip_dev1_hflip = 0
vip_dev1_iovdd = ""
vip_dev1_iovdd_vol = 2800000
vip_dev1_avdd = ""
vip_dev1_avdd_vol = 2800000
vip_dev1_dvdd = ""
vip_dev1_dvdd_vol = 1500000
vip_dev1_afvdd = ""
vip_dev1_afvdd_vol = 2800000
vip_dev1_power_en =
vip_dev1_reset =
vip_dev1_pwdn =
vip_dev1_flash_en =
vip_dev1_flash_mode =
vip_dev1_af_pwdn =

tvout_used = 0
tvout_channel_num =
tv_en = 0

tvin_used = 0
tvin_channel_num =

di_used = 1

sdc_used = 1
sdc_detmode = 3
sdc_buswidth = 4
sdc_clk = port:PF02<2><1><2><default>
sdc_cmd = port:PF03<2><1><2><default>
sdc_d0 = port:PF01<2><1><2><default>
sdc_d1 = port:PF00<2><1><2><default>
sdc_d2 = port:PF05<2><1><2><default>
sdc_d3 = port:PF04<2><1><2><default>
sdc_det = port:PF06<0><1><2><default>
sdc_use_wp = 0
sdc_wp =
sdc_isio = 0
sdc_regulator = "none"
sdc_power_supply = "none"

sdc_used = 1
sdc_detmode = 4
sdc_buswidth = 4
sdc_clk = port:PG00<2><1><3><default>
sdc_cmd = port:PG01<2><1><3><default>
sdc_d0 = port:PG02<2><1><3><default>
sdc_d1 = port:PG03<2><1><3><default>
sdc_d2 = port:PG04<2><1><3><default>
sdc_d3 = port:PG05<2><1><3><default>
sdc_det =
sdc_use_wp = 0
sdc_wp =
sdc_isio = 1
sdc_regulator = "none"
sdc_power_supply = "none"
sdc_2xmode = 1
sdc_ddrmode = 1

sdc_used = 0
sdc_detmode = 3
sdc_buswidth = 8
sdc_clk = port:PC05<3><1><2><default>
sdc_cmd = port:PC06<3><1><2><default>
sdc_d0 = port:PC08<3><1><2><default>
sdc_d1 = port:PC09<3><1><2><default>
sdc_d2 = port:PC10<3><1><2><default>
sdc_d3 = port:PC11<3><1><2><default>
sdc_d4 = port:PC12<3><1><2><default>
sdc_d5 = port:PC13<3><1><2><default>
sdc_d6 = port:PC14<3><1><2><default>
sdc_d7 = port:PC15<3><1><2><default>
emmc_rst = port:PC16<3><1><2><default>
sdc_det =
sdc_use_wp = 0
sdc_wp =
sdc_isio = 0
sdc_regulator = "none"
sdc_power_supply = "none"
sdc_2xmode = 1
sdc_ddrmode = 1

smc_used = 0
smc_rst = port:PA09<2><default><default><default>
smc_vppen = port:PA20<3><default><default><default>
smc_vppp = port:PA21<3><default><default><default>
smc_det = port:PA10<2><default><default><default>
smc_vccen = port:PA06<2><default><default><default>
smc_sck = port:PA07<2><default><default><default>
smc_sda = port:PA08<2><default><default><default>

usb_used = 1
usb_port_type = 2
usb_detect_type = 0
usb_id_gpio = port:PG12<0><1><default><default>
usb_det_vbus_gpio = port:PG12<0><1><default><default>
usb_drv_vbus_gpio = port:PL02<1><0><default><0>
usb_host_init_state = 1
usb_restrict_gpio =
usb_restric_flag = 0
usb_restric_voltage = 3550000
usb_restric_capacity = 5
usb_regulator_io = "nocare"
usb_regulator_vol = 0
usb_not_suspend = 0

usb_used = 1
usb_drv_vbus_gpio =
usb_restrict_gpio =
usb_host_init_state = 1
usb_restric_flag = 0
usb_regulator_io = "nocare"
usb_regulator_vol = 0
usb_not_suspend = 0

usb_used = 1
usb_drv_vbus_gpio =
usb_restrict_gpio =
usb_host_init_state = 1
usb_restric_flag = 0
usb_regulator_io = "nocare"
usb_regulator_vol = 0
usb_not_suspend = 0

usb_used = 1
usb_drv_vbus_gpio =
usb_restrict_gpio =
usb_host_init_state = 1
usb_restric_flag = 0
usb_regulator_io = "nocare"
usb_regulator_vol = 0
usb_not_suspend = 0

vendor_id = 6353
mass_storage_id = 1
adb_id = 2
manufacturer_name = "USB Developer"
product_name = "Android"
serial_number = "20080411"

vendor_name = "USB 2.0"
product_name = "USB Flash Driver"
release = 100
luns = 3

serial_unique = 0

module_num = 7
module_power0 = "vcc-wifi-33"
module_power0_vol = 0
module_power1 =
module_power1_vol =
module_power2 =
module_power2_vol =
module_power3 =
module_power3_vol =
chip_en =
lpo_use_apclk =

wifi_used = 0
wifi_sdc_id = 1
wifi_usbc_id = 5
wifi_usbc_type = 1
wl_reg_on = port:PL07<1><default><default><0>
wl_host_wake = port:PG10<0><default><default><0>
wl_host_wake_invert = 0

bt_used = 0
bt_uart_id = 1
bt_rst_n =
bt_wake =
bt_host_wake =
bt_host_wake_invert = 0

daudio_used = 0
daudio_master = 4
daudio_select = 1
audio_format = 1
signal_inversion = 1
mclk_fs = 128
sample_resolution = 16
slot_width_select = 32
pcm_lrck_period = 32
pcm_lrckr_period = 1
msb_lsb_first = 0
sign_extend = 0
slot_index = 0
slot_width = 32
frame_width = 0
tx_data_mode = 0
rx_data_mode = 0
i2s_mclk = port:PA18<2><1><default><default>
i2s_bclk = port:PA19<2><1><default><default>
i2s_dout0 = port:PA20<2><1><default><default>
i2s_din = port:PA21<2><1><default><default>

daudio_used = 0
daudio_master = 4
daudio_select = 1
audio_format = 1
signal_inversion = 1
mclk_fs = 128
sample_resolution = 16
slot_width_select = 32
pcm_lrck_period = 32
pcm_lrckr_period = 1
msb_lsb_first = 0
sign_extend = 0
slot_index = 0
slot_width = 32
frame_width = 0
tx_data_mode = 0
rx_data_mode = 0
i2s_mclk = port:PG10<2><1><default><default>
i2s_bclk = port:PG11<2><1><default><default>
i2s_dout0 = port:PG12<2><1><default><default>
i2s_din = port:PG13<2><1><default><default>

audio_used = 1
lineout_vol = 31
cap_vol = 5
audio_hp_ldo = "none"
adcagc_used = 0
adcdrc_used = 0
dacdrc_used = 0
adchpf_used = 0
dachpf_used = 0
audio_pa_ctrl = port:PA16<1><default><default><0>

spdif_used = 0
spdif_dout = port:PA17<2><1><default><default>

hub_used = 0
codec_used = 1
spdif_used = 1
hdmi_used = 1

ir_used = 0
ir_rx = port:PL11<2><1><default><default>
ir_power_key_code0 = 87
ir_addr_code0 = 40704
ir_power_key_code1 = 26
ir_addr_code1 = 64260
ir_power_key_code2 = 20
ir_addr_code2 = 32640
ir_power_key_code3 = 21
ir_addr_code3 = 32640
ir_power_key_code4 = 11
ir_addr_code4 = 63240
ir_power_key_code5 = 3
ir_addr_code5 = 239
ir_power_key_code6 = 159
ir_addr_code6 = 19635
ir_power_key_code7 = 10
ir_addr_code7 = 30536
ir_power_key_code8 = 69
ir_addr_code8 = 48386
ir_power_key_code9 = 77
ir_addr_code9 = 56865
ir_power_key_code10 = 24
ir_addr_code10 = 65025
ir_power_key_code11 = 87
ir_addr_code11 = 65280
ir_power_key_code12 = 77
ir_addr_code12 = 65344

ir_used = 1
ir_tx = port:PH07<2><default><default><default>

pmuic_type = 1
pmu_gpio0 = port:PL06<1><1><2><1>
pmu_level0 = 11300
pmu_level1 = 1100
max_freq = 1200000000
min_freq = 480000000
LV_count = 5
LV1_freq = 1200000000
LV1_volt = 1300
LV2_freq = 1008000000
LV2_volt = 1300
LV3_freq = 912000000
LV3_volt = 1100
LV4_freq = 648000000
LV4_volt = 1100
LV5_freq = 480000000
LV5_volt = 1100

G_LV_count = 3
G_LV0_freq = 312000000
G_LV0_volt = 1200000
G_LV1_freq = 384000000
G_LV1_volt = 1200000
G_LV2_freq = 456000000
G_LV2_volt = 1200000

Vdevice_used = 0
Vdevice_0 = port:PH10<5><1><2><default>
Vdevice_1 = port:PH11<5><1><2><default>

s_uart_used = 0
s_uart_tx = port:PL02<2><default><default><default>
s_uart_rx = port:PL03<2><default><default><default>

s_rsb_used = 1
s_rsb_sck = port:PL00<2><1><2><default>
s_rsb_sda = port:PL01<2><1><2><default>

s_jtag_used = 0
s_jtag_tms = port:PL04<2><1><2><default>
s_jtag_tck = port:PL05<2><1><2><default>
s_jtag_tdo = port:PL06<2><1><2><default>
s_jtag_tdi = port:PL07<2><1><2><default>

s_powchk_used = -2147483648
s_power_reg = 0
s_system_power = 50

scr_used = 0
scr_vccen = port:PA06<2><default><default><default>
scr_slk = port:PA07<2><default><default><default>
scr_sda = port:PA08<2><default><default><default>
scr_rst = port:PA09<2><default><default><default>
scr_det = port:PA10<2><default><default><default>

tsc_used = 0
tsc_clk = port:PE00<3><default><default><default>
tsc_err = port:PE01<3><default><default><default>
tsc_sync = port:PE02<3><default><default><default>
tsc_dvld = port:PE03<3><default><default><default>
tsc_d0 = port:PE04<3><default><default><default>
tsc_d1 = port:PE05<3><default><default><default>
tsc_d2 = port:PE06<3><default><default><default>
tsc_d3 = port:PE07<3><default><default><default>
tsc_d4 = port:PE08<3><default><default><default>
tsc_d5 = port:PE09<3><default><default><default>
tsc_d6 = port:PE10<3><default><default><default>
tsc_d7 = port:PE11<3><default><default><default>

key_used = 1
key_io = port:PL03<6><default><default><0>

key_used = 0
key_cnt = 5
key1_vol = 222
key2_vol = 444
key3_vol = 666
key4_vol = 857
key5_vol = 2000

d7s_used = 0
din_gpio = port:PD00<1><default><default><1>
clk_gpio = port:PD01<1><default><default><1>
stb_gpio = port:PD02<1><default><default><1>

mali_used = 1
mali_clkdiv = 1
mali_extreme_freq = 600
mali_extreme_vol = 1400

w1_used = 1
gpio = 20

corekeeper_enabled = 1


Posted in c-opi | Tagged | Leave a comment

Orange PI One Installation

I picked up an orange pi on ebay to experiment with. The smallest ones are really cheap (~$10) and have the only ports I need – Ethernet/RJ45 and a USB port. I just need to be able to ssh into the Orange Pi and then use it to program a Teensy MCU. It appears I should be able to do this though the Teensy loader is still questionable.

Unlike the Raspberry Pi, documentation and help is not as forth coming for the OPI. I wasted hours trying to figure out why my monitor was showing horrible colors (HDMI to DVI is not supported out of the box).

My primary instructions were the orange pi quick start.

This post is a very brief list of the steps I had to follow to get the OPI running. If you need hand-holding, you will be better off finding other instructions.

What You Will Need

  • Orange Pi One (the instructions probably work for other models, but that is the model I’ve tested them with).
  • Class 10 Micro SD card. I used 32GB, but 8GB is the minimum.
  • mini hub for keyboard + mouse (there is just one USB port).
  • keyboard
  • mouse
  • HDMI cable + HDMI monitor. DVI monitors will not work. I’ve included, at the end, how I got mine to work, but chances are you won’t be as lucky.
  • ethernet cable connected back to LAN
  • DC 5v power supply >= 2A. Note the 1.7mm jack which is a lot smaller than the 2.1mm jack I normally use. My power supply has a 1.7mm. If you only have a 2.1mm power supply, there are 2.1mm to 1.7mm jack converters available at amazon.

Prep the SD Card

  • Use SDFORMATTER to format the SD Card
  • Download the Raspbian O/S for OPI ONE from here.
  • This downloads as an .XZ file. This is compatible with 7Z files.
  • Extract the image from the .XZ file. Note that I had to use the extract button. Dragging the file to the desktop failed with an error.
  • Using Win32 Disk Imager, copy the image to the SD card

Prep the Hardware

  • Attach heat sink to OPI’s CPU
  • Put OPI into case. The case I have has a front that blocks all venting. I removed that cover.
  • Insert the SD card into the OPI
  • Connect all of the cables
  • Provide power to start the OPI

The login for raspbian is root and password is orangepi.

Dealing with DVI

From what I’ve been able to tell some DVI monitors won’t work at all, some will show totally screwed up colors. From what I can tell this seems to depend on if the monitor recognizes HDCP (and I could be totally wrong about that).

If your DVI monitor shows nothing, I don’t think this next procedure will work (and if your monitor shows nothing there’s really no way to actually do this procedure without first connecting to an HDMI monitor).

I used these resources to figure this out:


  • sudo su
  • cd ~
  • apt-get install libusb-1.0.0-dev
  • git clone
  • cd sunxi-tools
  • make tools
  • make install-tools (may be make tools is not needed when using this, but this is required to move tools into /usr/local/bin)
  • cd /boot
  • cp script.bin script.old # backup copy
  • bin2fex script.bin script.fex (got some warnings, mainly on comments)
  • now find [hdmi_para] section and add:
    • hdcp_enable = 0
    • hdmi_cts_compatibility = 1
  • save file
  • fex2bin script.fex script.bin
  • reboot

Next I will alter the operating system to follow my standard config (such as installing VNC). If I find any oddities in OPI vs RPI in this regard, I’ll report them next.

Posted in c-opi | Tagged | 1 Comment

Providing increased water flow for a 5G Bucket Evaporative Cooler

I recently built a 5G bucket swamp cooler very similar to this:

I used a tack like he does to puncture the water supply hose and I simply could not get enough water to keep the pad moist. I went back and used a much larger nail and still the water supply was too constricted to do the job.

I ended up using a razor to slice the hose and that finally started producing reasonable water flow.

To do this:

  • Lay the tube flat, letting it naturally coil so you are working with the existing coil.
  • Using a sharpie, run a line along the top of the tube for the length of it so you are cutting only the bottom (I don’t want water shooting up, just down).
  • Make another mark on the hose indicating where the cuts need to stop – beyond that point, the hose goes down into the pump.
  • Now that the hose is marked, use a razor to slice the hose perpendicular to its length.
  • I made each cut a little less than 1/2 the diameter of the hose.
  • I separated the cuts by about 1/4″.

After you do this, you should find the water only shoots down toward the pad and there is enough flow thru the slits to keep the pad moist.

BTW, I am generally seeing a 10 degree temp difference with my cooler. I expect to field test it next week.

Posted in c-Misc | Tagged , | Leave a comment

Forcing Accelerator Key Labels ALWAYS ON in Linux Mate

Need to file this one away for future use.

In Linux Mint / Mate, the underscores for accelerators keys is only on when you hold down ALT. I invariably forget this because they aren’t obvious, and don’t make use of them which slows me down. I *hate* having to use the mouse.

Tonight I went looking to see if they could be forced to stay on.

The few instructions I’ve found tell you to set the gnome setting “automatic-mnemomics” to false. I tried that repeatedly w/ no luck.

Eureka! I am using MATE not gnome. Doh! went looking in the Mate section of dconf settings and found the exact same setting. Set that to false and now underscores are always on.

Note: install dconf-editor. This is much easier than using gsettings and typing everything by hand.

The specific tree to this setting is:

org.mate.desktop.interface automatic-mnemonics

Posted in c-Misc | Tagged | Leave a comment

Cermetek CH1724 Modem PTH Adapter Board

I need to solder pins to multiple CH1724 modems which look like this:

Image result for ch1724

I tried soldering header pins directly, but that was a cluster. So I designed this little adapter board:

You can layout header pins on a PCB, put the adapter board on the pins, then the modem on the adapter board like this:


and you end up with:


I’ve placed this adapter board on so you can order your own. You can find it here.

If you need such a beast and you don’t want to order a minimum quantity of 10, check with me and I may have a spare I can send you cheap.

Posted in c-electronics | Tagged | Leave a comment

WiFi Target Spotting Scope

DISCLAIMER: If you build this device, I take no responsibility for any outcome. Make sure you are sighted-in well enough to be hitting the target everytime and place the equipment in a position to avoided being hit. Lithium batteries are particularly dangerous and hitting one with a bullet will have a nasty outcome such as this:

wtss-fig32A friend and I were looking at a very cool commercial WiFi target spotting scope. It lets you see easily see a shooting target from your phone / tablet and software tracks each shot. Cool but at $350, we weren’t really interested. We bounced around some ideas and found someone using a WiFi router and IP camera to do the same thing. Genius!

That guy’s rig was just a 20 second YouTube clip with no setup instructions. I’ve duplicated his effort, but documented exactly what you need to make this happen.

I’m using a D-Link DCS-920 WiFi camera because that is what I have laying around. It is very old and the video part doesn’t work with Java any longer; however, it will take still pictures fine which is all I really need (I just press refresh to update the picture). If you are a shooter and not a computer person, you should be able to find one of these used on eBay if you want to follow my instructions to the letter. As of writing, the going used price is $20-$50.

I’m also using a TP-Link TL-WR802N because that was just laying around as well. If I were trying to create a serious spotting scope, I’d go with a router that has external antennas so it has the maximum possible range. Since this project is expected to be used outdoors with no obstructions, the TL-WR802N is acceptable, at least as far as I am capable of hitting a target. As of writing, this is a current device that can be had on amazon for about $25.



  • Laptop and RJ45 Cable (for setup). Laptop needs both a WiFi connection and an Ethernet connection.
  • 5V WiFi Router (TP-Link TL-WR802N) and USB Type A to Micro USB power cord
  • 5V WiFi Video Camera (D-Link DCS-920)
  • USB Type A to 2.1mm Barrel Jack Power cord (Adafruit model 2697)
  • USB Lithium Phone charger to provide 5V power to router and camera.
  • Paperclip to reset devices

Configure the WiFi Router

The WiFi Router will be configured to be a wireless router which will allow your phone/tablet/PC to access the WiFi Camera via WiFi (note that android doesn’t support adhoc access, so a WiFi router is required).

These instructions are specific to configuring the TL-WR802N, but the same general configuration will apply to other routers.

  • Reset router to factory defaults. For TL-WR802N, press reset button and hold for 10 secs. Green light will go to fast blinking.
  • Wait for the light to flash slow again – then it is fully rebooted.
  • Using the laptop, find the router’s WiFi network which is called TP-LINK_090A and establish a connection to it. The WiFi password is on the back of the router.



  • Login to the router. For the TP-Link, the user / pass is admin / admin.
  • This takes you to the Quick Setup starting screen. Click on Next.
  • Operational Mode: Select wireless router and click on Next. Don’t use Access Point – it will not assign DHCP addresses properly.


  • WAN connection type. Select Dynamic IP and click on next.


  • MAC Clone: Select No and click on next.


  • Wireless Setup. Enter the SSID and password you wish to use then click on next.


  • In the review settings screen, verify all settings and click on finish.
  • The router will now reboot. You will need to reconnect to it using the new SSID, wifiscope:


  • You may notice an exclamation point for your wifi connection. This just means there is no connection to the internet, which is correct.


  • The router is now configured to use IP address Ping it to verify you can still get to it.

Configure the IP Camera

Next, the DCS-920 will be configured to use the WiFi router.

This camera can be a bit confusing. Although it has both an ethernet and wifi connection, they BOTH are assigned to the same IP address. Remember that as you go thru the configuration.

  • Provide power to the camera.
  • Reset camera to factory defaults. For DCS-920, press reset button and hold for 10 secs.
  • Set up laptop’s ethernet port to the same default subnet as the WiFi IP camera. For the DCS-920, this is, so my laptop is given the address


  • Connect camera to laptop via RJ45 cable.
  • Laptop’s ethernet port should now be in connected state.


  • Determine IP address of the camera.
    • By default, DCS-920 is assigned IP address of
    • I determined this by running a TCP port scanner on the laptop against the network.
    • Typically the default address will be on the label of the device or in the manual.
  • From the laptop, ping the camera ( to verify you can reach it.
  • Now connect to the camera via your web browser using the IP address:
    • HTTP://
    • You will be asked for the camera’s user/password. for the DCS-920 this is admin and the password is blank.
    • Once logged in, the main screen is displayed:


  • Click on the Setup Tab, then on Network Setup on the Left tabs. Assign the camera a static IP address. I will use the default of here. Then click on Save Settings.


  • Now go to the Wireless Setup tab. Enable wireless, and specify SSID, security mode, and the password. Then click on save settings.


  • Go to status screen and keep pressing refresh until you see the link come up:


  • For the DCS-920, I left the image settings as defaults. I went into the video setup and changed resolution from 320×240 to 640×480 and quality to high.


  • Now I can see a reasonable image in the browser.

Test WiFi Access to Spotting Scope from Laptop

Now let’s make sure everything works properly.

  • Disconnect the Ethernet cable from the camera.
  • Make sure the laptop is connected to the wifiscope SSID.
  • From the laptop, ping, the camera.
  • From the laptop’s browser, connect to, the camera.

Test Phone / Tablet

If the laptop is working, time to connect using your phone.

  • Connect to the WiFi SSID wifiscope and enter the appropriate password. For my version of android, I got a warning there is no internet connectivity which is correct.
  • While in the list of networks, click on the 3 dots (submenu) and then on advanced.  Verify you have an IP address assigned to your phone.
  • Note: I’ve had some issues getting the phone to receive DHCP (the router says it sends it). If this is a problem for you, you can configure your phone to use a static IP address on this network (say
  • In the phone browser go to
  • Enter the user / password for the camera (still admin / nothing for my DCS-920).
  • You will now see the camera website.

Create a link to just the Picture

I’m using firefox on my phone, so this is how to create a link to just the picture.

  • Long press the picture on the website until you get a menu.
  • From the menu select view image.
  • You will now see just the picture, not the entire web page.
  • Bookmark this page and call it something like wifiscope.
  • Because this is NOT a video, it will only update if you press the browser refresh button.

Field Setup

Setting the camera up in the field is pretty straight forward. Plug everything in, and go to the bookmark you saved above with your phone/tablet. Using the phone, you can position the camera as you need it.

Obviously, position the camera where it can’t get hurt. More importantly, make sure the battery pack CANNOT get hit. As already pointed out, hitting the lithium battery would result in a fire.

When I’m ready to use this, I will use a barrel jack extension cord to separate the camera from the router and battery pack so both can be position well out of the line of fire.

Note that the DCS-920 has a manual focus ring.

Here is my test setup (done inside because it is miserable out today):


Clean Up

Don’t forget to reconfigure your laptop’s Ethernet interface back to it’s original settings.

Posted in c-Misc | Tagged | Leave a comment

Tip o’ the Day: Gaffer Tape instead of Duct Tape

Duct tape is renown for its usefulness.  No argument there – I keep rolls in my vehicles, snowmobiles, ATVs, etc. for emergencies.

Interestingly, it sucks for use on actual ducts. I tried that many years ago only to have the tape completely fall off after several months.

I was introduced to Gaffer Tape many years ago by a professional photographer friend. It is typically my go to tape these days.

It is easier to tear, a bit more like cloth so it conforms better if you aren’t taping flat surfaces, and best of all it doesn’t leave a mess when you remove it.

It is more expensive than duct tape, so I still keep cheap duct tape in my vehicles for emergencies. But around the house, gaffer tape is my go to tape.


Posted in c-photo | Tagged | 1 Comment

Cleaning Flux from Printed Circuit Boards (PCB)

I got some professional looking PCB boards manufactured for a project recently. The boards look great compared to anything I could do myself.

Problem is, after I solder on the components and try to clean the flux off, I’m always left with a mess. My great looking boards end up with white stains from trying to remove the flux.

In researching this problem, I’ve learned about water soluble solder and no clean solder. I will be trying those in the future, but I’m still left with my most recent board which needs to be cleaned.

After looking around the interweb and doing some experiments here is what worked very well (though not quite perfect).

  • Apply all liquids with the board vertical to avoid getting anymore than necessary on the front side of the board.
  • Apply 99.9% isopropyl alcohol with a toothbrush to remove the flux. I don’t seem to need to scrub long or hard to get it loosened up.
  • Apply Simple Green with a sprayer. Brush the whole board again with a toothbrush. It may help to apply plenty of Simple Green to help flush the flux away.
  • Spray the board repeatedly with distilled water until the simple green & flux are flushed from the board.
  • Blow excess water off board with compressed air.
  • Finally, dry the board with a heat gun or hair dryer, taking care not to let it get too hot.


Posted in c-electronics | Tagged | 2 Comments

Automating Testing Using Video

I found myself needing to verify caller ID operation of a couple of troublesome telephone handsets. To properly test, I want to run 1,000 calls to the handsets and verify they decode caller ID every single time.

During early testing, I would manually call the handsets about 20 times to see if they looked good. Typically the error occurs every 3rd-4th call so that was a little slow but do-able. But there is no way I’m sitting still to watch 1,000 calls.

I could video record the handsets, but watching the video is no faster and trying to fast forward was going to be clumsy as well.

What I really need is a way to toss out most of the video frames then I could just advance a few frames to see the next call.

I recorded the video off a webcam using VLC using this procedure:

After some research I found a utility call ffmpeg which does many things, but for my current need, you can tell it to extract <n> frames per second and save them as a file.

ffmpeg can be found here:

My first test was to extract one frame per second which I did with this command:

    ffmpeg -i myfile.mp4 -vf fps=1 c:\tmp\pics\out_%%03d.png

This created a PNG file once a second (1 frame per second), reading myfile.mp4 and creating a series of PNG files called out_001.png, … .

This worked pretty well, but a complete test cycle takes about 20 seconds so I was ending up with 20 PNG files / cycle to flip thru. That’s too many.

I watched the testing process, and both phones’ displays are on for about 10 seconds from the time the CID message comes thru. If I were to capture a frame every 5 seconds, that would be about perfect.

So I ended up using this command:

    ffmpeg -i myfile.mp4 -vf fps=0.2 c:\tmp\pics\out_%%03d.png

Now I end up with about 5 frames per test call.

Using picasa to view the first file, I can go to the first picture showing the caller ID message. Then I just press the right key 5 times and I’m on the same spot in the next test. That I can do very quickly.

I can process roughly 1 test every 2-3 seconds flipping thru 5 pics verses having to watch hours of video which just isn’t going to happen.



I’ve went thru this process quite a few times now. Works well, but having to constantly click thru still images is a pain.

So using ffmpeg again as directed here:

I created a video to watch. I can then stare blankly at the video and just pause when I think an event has been missed.

When I did the extract, I was extracting 1 frame from the original video every 10 seconds. When I create the new video, I want to see each of those extracted frames every 1/2 second (2 frames per sec). This is the command I used to construct the video:

"\Program Files\ffmpeg\bin\ffmpeg.exe" -framerate 2 -i f11b_%%04d.jpg -c:v libx2
64 -r 30 -pix_fmt yuv420p outx.mp4

My input file is f11b_0001.jpg, f11b_0002.jpg, …

My output file is outx.mp4

I’m reading these jpg files at a rate of 2 / sec (-framerate 2).

The output MP4 file contains 30 frames per sec (-r 30).


Posted in c-Misc | Tagged | Leave a comment