Internet Ping Meter (part 2 of 2)

Onto the fun stuff!  Below is the python script that does most of the heavy lifting.  Remember with Python, indentation is critical.  It’s actually used to delimit things like functions rather than more traditional delimiters like {}.  Best practice is to use spaces, not tabs for indentation because they can be inconsistent and cause problems.  To avoid this, I like to use an IDE such as notepad++ or the Arduino IDE. It does a great job of taking care of the spacing and indentation. It will even go through the entire script and fix any indentation errors you have automatically. Highly recommended. FYI- You’ll also need to install the PySerial module for this to work:

#!/usr/bin/python

##
## Internet Ping Meter v1.0 - Eric Steed
##
## 01/03/17 - first version - EPS
##
import serial
import sys
import subprocess
import time
latency = 0
ping_targets="8.8.8.8 4.2.2.2 208.67.220.220"
retVal = 0
failLevel = 0
lastLEDStatus = ""

##
## Define array variable alertLevel[] and assign color codes to be sent to the NeoPixel.
## Based on the number of total ping failures, iterate the failLevel by one and
## send the appropriate color code.
##
clearLED = "ic"
alertLevel = []
alertLevel = ["h","g","f","e","d"]

##
## Open the serial port to talk to the NeoPixel. Have to wait for it to initialize
## before we start sending signals
##
port = serial.Serial("/dev/ttyACM0", baudrate=9600, timeout=1)
time.sleep(3)

##
## Green = h
## Greenish Yellow = g
## Yellow = f
## Orange = e
## Red = d
## Black = i
##
## LED #'s
##
## 1-9 = 1-9
## 10 = a
## 11 = b
## 12 = c
##
##
## I'm using a NeoPixel ring with 12 LED Segments to indicate the average latency of
## multiple established servers on the internet.  This way I can tell visually if
## my internet connection is slow, or even down.
##
## To control the NeoPixel, I've assigned specific characters to indicate how many
## LED's to illuminate and what color.  When we tell the NeoPixel to illuminate a
## given number of LED's, we have to account for the fact that the last command
## string that was sent is persistent in that the LED stays lit even when the next
## command string comes in.  For example, if reading 1 determines that 4 LED's
## should be lit, then reading 2 calls for 3 LED's, you wouldn't be able to see that
## because all 4 LED's were still illuminated from the previous cycle.
##
## To account for this, we send an instruction to "illuminate" all 12 LED's with
## the color Black before sending the actual value desired.  This is done by
## assigning a value of 'ic' to the variable clearLED.  I've also added some logic
## at the end of the infinite while loop that says don't send any instructions
## unless there's been a change since the last one.  This gets rid of the blinking
## effect that I was seeing on every update- rather annoying!
##

##
## I'm using the subprocess library for now unless I can get the native Python ping library
## to do it for me.  If stdout is null for a given target, return 0.
##
def doPing(host):
    import os,platform
    pingOutput = subprocess.Popen(["ping -c 1 -w 1 " + host + " | grep rtt | awk -F/ '{print $5}' | awk -F. '{print $1}'"], stdout=subprocess.PIPE, shell=True)
    (out, err) = pingOutput.communicate()
    if (out.rstrip('\n') == ''):
        return 0
    else:
        return out.rstrip('\n')

##
## Get average latency from all of the ping targets. Had to cast the output of
## doPing() into an integer to be able to do math against it
##
while True:
    count=0
    for x in ping_targets.split():
        retVal = int(doPing(x))
        #print "latency = [{0}]".format(retVal)
        # print "type = [{0}]".format(type(retVal))
        if (retVal > 0):
            latency += retVal
            count+=1

    ##
    ## If count is zero, that means we were not able to successfully ping
    ## any of the targets and we should start incrementing the failure count.
    ## Furthermore, if we have been incrementing failLevel and we are now
    ## able to ping, reset the failLevel back to 0 at that time.
    ##
    if (count == 0):
        # Increase failure level
        #print "Failed to ping any host"
        failLevel += 1
        if (failLevel > 4):
            failLevel = 4

    else:
        latency=(latency/count)
        failLevel = 0

    ##
    ## Set LEDStatus to the appropriate value based on latency and failure count
    ##

    #print "Average Latency = [{0}]".format(latency)

            if (latency > 1) and (latency <= 10):                 #print "1-10"                 LEDStatus = clearLED + alertLevel[failLevel] + "1"         elif (latency >= 11) and (latency <= 20):                 #print "11-20"                 LEDStatus = clearLED + alertLevel[failLevel] + "2"         elif (latency >= 21) and (latency <= 30):                 #print "21-30"                 LEDStatus = clearLED + alertLevel[failLevel] + "3"         elif (latency >= 31) and (latency <= 40):                 #print "31-40"                 LEDStatus = clearLED + alertLevel[failLevel] + "4"         elif (latency >= 41) and (latency <= 50):                 #print "41-50"                 LEDStatus = clearLED + alertLevel[failLevel] + "5"         elif (latency >= 51) and (latency <= 60):                 #print "51-60"                 LEDStatus = clearLED + alertLevel[failLevel] + "6"         elif (latency >= 61) and (latency <= 70):                 #print "61-70"                 LEDStatus = clearLED + alertLevel[failLevel] + "7"         elif (latency >= 71) and (latency <= 80):                 #print "71-80"                 LEDStatus = clearLED + alertLevel[failLevel] + "8"         elif (latency >= 81) and (latency <= 90):                 #print "81-90"                 LEDStatus = clearLED + alertLevel[failLevel] + "9"         elif (latency >= 91) and (latency <= 100):
                #print "91-100"
                LEDStatus = clearLED + alertLevel[failLevel] + "a"

        else:
                #print "latency greater than 101"
                LEDStatus = clearLED + alertLevel[failLevel] + "c"

    ##
    ## If the latency is within a different range than the last iteration, send
    ## the command to update the LED count on the NeoPixel.  Otherwise you get
    ## a rather annoying blinking effect as the LED's are updated even if it's the
    ## same measurement as the last time.
    ##
    if (LEDStatus != lastLEDStatus):
        port.write(LEDStatus)
        lastLEDStatus = LEDStatus

    #time.sleep(5)
    #print LEDStatus
    latency = 0

I left the debugging code in the script if you want to uncomment them and watch the terminal as the script runs to see what’s going on. Most of the script is fairly straightforward so I won’t dwell too much on explaining it step by step.

Now, onto the Arduino code. I’m using the Arduino basically as a driver for the NeoPixel. Again- I could have probably just used the Pi by itself, but what fun would that be?

#include <Adafruit_NeoPixel.h>

//
// Internet Ping Meter v1.0 - Eric Steed
//
// 01/03/17 - first version - EPS
//
// Set up variables
byte leds = 0;
uint8_t delayVal = 30;

// Set the PIN number that the NeoPixel is connected to
#define PIN   7

// How bright are the LED's (0-255)
#define INTENSITY 60

// Set color to Green to start
uint8_t  r = 0;
uint8_t  g = INTENSITY;
uint8_t  b = 0;

// Set the number of pixels on the NeoPixel
#define NUMPIXELS   12

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

// Initialize everything and prepare to start
void setup()
{
  uint8_t i;

  // Set up the serial port for communication
  Serial.begin(9600);
  Serial.println("Started Serial Monitor");

  // This initializes the NeoPixel library.
  pixels.begin();

  // This sets all the pixels to "off"
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }

  // Cycle each pixel through the primary colors to make sure they work, then turn them all off
  // Red
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(INTENSITY, 0, 0));
    pixels.show();
    delay(delayVal);
  }

  // Green
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, INTENSITY, 0));
    pixels.show();
    delay(delayVal);
  }

  // Blue
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, INTENSITY));
    pixels.show();
    delay(delayVal);
  }

  // White
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(INTENSITY, INTENSITY, INTENSITY));
    pixels.show();
    delay(delayVal);
  }

  // Turn off all LED's
  for (i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}

// Main loop
//
// When sending LED signals, send the color code first, then the number of LED's to
// turn on.  For example 6 Green LED's would be h6, 11 Red LED's would be db, all
// 12 LED's to Black would be ic
void loop()
{
  uint8_t i;
  if (Serial.available())
  {
    char ch = Serial.read();
    // Serial.print("ch = ");
    // Serial.println(ch);
    int led = ch - '0';

    // Serial.print("led = ");
    // Serial.println(led);

    // Set Color of LED based on how many fails in a row
    //RED = 52(d)
    //ORANGE = 53(e)
    //YELLOW = 54(f)
    //YELLOW-GREEN = 55(g)
    //GREEN = 56(h)
    //BLACK = 57(i)

    switch (led) {
      // Set color to RED
      case 52: {
          r = INTENSITY;
          g = 0;
          b = 0;
        }
        break;

      // Set color to ORANGE
      case 53: {
          r = INTENSITY;
          g = (INTENSITY / 2);
          b = 0;
        }
        break;

      // Set color to YELLOW
      case 54: {
          r = INTENSITY;
          g = INTENSITY;
          b = 0;
        }
        break;

      // Set color to YELLOW-GREEN
      case 55: {
          r = (INTENSITY / 2);
          g = INTENSITY;
          b = 0;
        }
        break;

      // Set color to GREEN
      case 56: {
          r = 0;
          g = INTENSITY;
          b = 0;
        }
        break;

      // Set color to BLACK
      case 57: {
          r = 0;
          g = 0;
          b = 0;
        }
        break;

      // To save on code, if we receive a 0 through a 9, turn on that
      // number of LED's
      case 0 ... 9:
        for (i = 0; i < led; i++) {
          pixels.setPixelColor(i, pixels.Color(r, g, b));
          pixels.show();
        }
        break;

      // If we receive an "a", turn on 10 LED's
      case 49:
        for (i = 0; i < 10; i++) {
          pixels.setPixelColor(i, pixels.Color(r, g, b));
          pixels.show();
        }
        break;

      // If we receive a "b", turn on 11 LED's
      case 50:

        for (i = 0; i < 11; i++) {
          pixels.setPixelColor(i, pixels.Color(r, g, b));
          pixels.show();
        }
        break;

      // If we receive a "c", turn on 12 LED's
      case 51:

        for (i = 0; i < 12; i++) {
          pixels.setPixelColor(i, pixels.Color(r, g, b));
          pixels.show();
        }
        break;

      // For testing, insert a delay if we see a ,
      case -4:
        delay(delayVal * 10);
        break;

      default:
        // if nothing else matches, do the default
        // default is optional
        break;
    }
    // I had to add this bit of code to fix a problem where the Arduino buffer
    // apparently filled up after a very short time.  It would set the LED's on
    // but then pause for 2-3 seconds before it would receive the next command.
    // This tells the Arduino to flush out the buffer immediately.
    Serial.flush();
  }
}

If it’s not already evident, I’m not very adept at either Python or Arduino coding. I’m just starting out. The most frustrating thing for me is stumbling across syntax issues with code. 9 times out of 10, I know it’s possible to do something but I just can’t get the syntax right or use the correct modules. All this comes with time so maybe in a year, this code would be half or 1/3 the size it is right now.

Once you have everything installed and tested (you can turn on and off the LED’s), you have to connect the Pi to your network. I would consider this device to be a single purpose device and not put anything else on it that could interfere with the script and timing. They’re cheap enough that you should be able to justify this.

 

You can find this code on Github at https://github.com/esteed/Internet-Ping-Meter.  Please feel free to make modifications and generate a pull request- I’m always looking for a better mousetrap!

 

I hope this has helped you even a little bit. I had a great time setting it up and I look forward to making enhancements. The first one will be to indicate current upstream and downstream throughput using white and blue LED’s basically overlaid on the top of the latency indicators. Wish me luck!!

Internet Ping Meter (part 1 of 2)

THE INTERNET IS DOWN!!

How many of you “home IT support technicians” have heard this before?  I hear it a lot, so I decided to create a device that would notify me visually when problems occur.  Sometimes it winds up being a flaky wifi router that either reboots or just needs to take a breath.  Other times, it’s our Comcast connection in which case I can’t do anything other than call and file an outage.  The kids seem to have a hard time with understanding that even though I’ve explained it to them a hundred times.

A little background on the reason for this project.  At the company I work for, we employ a WAN load balancer which uses a series of pings to major internet presences such as google, AT&T or OpenDNS servers.  Basically the device pings each of those addresses once per second and based on specific criteria, can determine if one of the two internet connections is down and can take appropriate action.

This is what made me decide to develop my version of the ping meter.  There are a number of projects like this for the raspberry pi that involve some sort of visual representation.  I wanted to put together a project that incorporated both the raspberry pi, an arduino board and the NeoPixel ring.  This was mainly a project for me to learn how to integrate multiple devices.  Honestly I could probably have done this without the Arduino but I wanted to challenge myself a little.

At this point, I have the device working the way I want.  My next challenge is to package the device into something more aesthetically pleasing.  WAF (Wife Acceptance Factor) is an important aspect to any geek project like this if it’s gonna be displayed somewhere that’s visible.  I’m thinking maybe a small picture frame or maybe some sort of glass object that looks nice.

Here is a list of the parts you’ll need:

  • Raspberry Pi (any model should work)
  • Arduino board (I used an UNO but even that is overkill)
  • NeoPixel LED ring (12 LED segments)
  • Micro SD card (at least 4gb)
  • USB Type A to USB type B (printer/scanner cable)
  • 5V Micro USB power source (iPad charging brick is perfect)

I haven’t tested using a Pi Zero yet but I don’t see why it wouldn’t work.  I also have an Arduino Trinket (5v version) that I’m trying to use for this however out of the box it doesn’t support serial communication.  For size reasons, this combination would be perfect for just about any implementation where room is an issue.  You could just as easily use a larger NeoPixel ring or even a strip with some very minor code modifications.

There are two programs that are used to make this system work.  One is the “firmware” that you load onto the Arduino board itself.  The other is the python script that runs on the Pi.  Basically I use the Pi to ping 3 different IP addresses, and use the NeoPixel ring to display the average ping latency in LED segments.  If I can’t ping all three then I start to progressively change the color of the LED’s from green to red.  Throughout this project I learned a lot about programming in python, Arduino and interacting with external physical devices.  I first started by just getting the LED’s to turn on and off.  I borrowed a lot of code from examples and implemented the same routines to get the NeoPixel to do what I wanted to.

I tried to sprinkle comments throughout the code to explain what I’m doing and why.  Most of these were added after I made a breakthrough in something that was kicking my ass for awhile so I would know how to fix the problem the next time around.  I won’t focus a lot on how to install the OS on your Pi or how to download code to the Arduino- there are a LOT of helpful resources on the internet that can walk you through it.  Also, in the spirit of this being a learning exercise for me- I think it’s valuable for someone starting out fresh to do the research and have a basic understanding of what’s going on rather than just copying and pasting code.  If you’re trying to put this together and run into problems, feel free to comment on the article and I’ll do my best to answer questions.

In the next article, I’ll show you the code and how it all works.  Stay tuned!

What do a Subway sandwich and a computer have in common?

original raspberry-pi-zero-_3510862b

 

That’s right, you can get either one of them for $5!  Introducing the newest member to the Raspberry Pi family, the Pi Zero.  As you can see by the picture above next to the deck of cards, it’s quite a bit smaller than a foot long sandwich, but that doesn’t stop it from packing quite a punch!  The tiny new SOC (System On a Chip) computer is just that- a full fledged computer capable of running Linux with a desktop environment.  Granted, it’s not the snappiest performer in that capacity but still super cool that it can pull it off!

 

Here are the specs (gratuitously lifted from raspberry pi’s website):

  • A Broadcom BCM2835 application processor
    • 1GHz ARM11 core (40% faster than Raspberry Pi 1)
  • 512MB of LPDDR2 SDRAM
  • A micro-SD card slot
  • A mini-HDMI socket for 1080p60 video output
  • Micro-USB sockets for data and power
  • An unpopulated 40-pin GPIO header
    • Identical pinout to Model A+/B+/2B
  • An unpopulated composite video header

 

So- on to the gotcha’s.  With a $5 computer, yo’re gonna to have to make some minor investments in additional hardware to make it functional.  Here’s the list of absolute must have’s to even get up and going:

  • MicroSD Card (preferably 8gb or bigger and class 10 or faster)
  • Micro USB power source capable of providing at least 1A at 5v
  • Micro USB to USB Type A Female converter
  • USB Wi-Fi or ethernet adapter (make sure it’s supported first)

You can technically get up and running with this much hardware, however you have no video out and would have to rely on pre-configuring the OS to somehow get on the network and allow SSH to get in.  Not very functional but a working minimal config once you have it set up the way you want.  Raspberry Pi has taken the Spirit Airlines approach to the Zero.  They give you only what you need to work (the Bare Fare), allowing you to decide what extras you want to pay for and which ones you skip.  In order to configure your Zero initially, you’ll need a couple more things:

  • Mini HDMI to HDMI cable (or Mini HDMI to HDMI converter with an HDMI cable coming out of it)
  • USB Hub for mouse, keyboard and wired or wireless network connectivity
  • Keyboard and Mouse

This will get you connected to a Monitor/TV that has HDMI inputs so you can see what you’re doing.  It also provides for an input method via the keyboard and mouse.  At the end of this article, I’ll post a list of some of the essential hardware, how much I paid for it and where I got it.

 

t5WCokG

One of the reasons I bought one of these is it’s ability to serve as a very capable media center device.  In one of my earlier posts, I talked about something called OpenELEC.  It’s a Linux distribution that includes Kodi which is an open source home theater software package also based on Linux.  The OpenELEC package combines the Linux OS and Kodi into an interface that’s very well suited to a TV and remote control.  Best of all, it runs on the entire line of Raspbery Pi’s!  I’ll be posting soon about one of the other alternatives to OpenELEC called OSMC.  The concept is the same, however OSMC includes a full raspbian Linux OS that isn’t as hands off as OpenELEC is.  As a result, it’s much more easily configured and customized without having to learn all the in’s and out’s of the underlying OpenELEC OS components.

 

Architecture-and-Source

The reason that the Zero can pull this off is mainly due to it’s built in hardware video decoder.  The GPU (Graphics Processing Unit) has discreet hardware functions dedicated for video encoding and decoding (recording and playback).  This means that video playback such as 1080p at 60fps doesn’t rely on the processor to decode and display the video stream, slowing other operations down.  It’s all done in hardware- very similar to the Playstation 4, XBox ONE, or any other gaming platform that has dedicated graphics hardware.  All that’s left for the diminutive Zero to do is render the on-screen menus, take care of assorted housekeeping and perform other OS related stuff.

 

Pibow_Zero_1_of_3_1024x1024There are a number of “cases” for the Zero out on the market now.  I use the term case rather loosely because as you can see to the left, it’s mainly two layers of plastic sandwiching the Pi Zero between it.  There are also quite a few 3d designs that “makers” can download and print on their 3d printer. Others can be bought in brick and mortar stores like MicroCenter or ordered online from websites like Adafruit, Raspberry Pi’s swag store, or Pimoroni (a popular “maker” website based in the UK) to name just a few.  You don’t technically need a case, but it’s a good idea to keep shorts, static discharge or any other molestation from occurring to your sweet innocent little computer.  With the tiny form factor this device affords, you can easily slap a case on it, connect it to your living room TV and attach it to the back of your set via 2 way adhesive tape- nobody would even know it’s there!

 

As of this writing, I’m not aware of any MicroSD cards that are bigger than 512gb.  Granted that’s a LOT of storage but that comes at a fairly steep price- about $400 on amazon.com.  I’m sure as higher density chips come out that price will fall, but the better bet would be to cobble together some 4TB hard drives in a desktop computer and use it for network storage of your multimedia files.  This is what I’m doing and it works perfectly!  I have multiple Raspberry Pi’s throughout the house on each TV that can play back my entire collection of movies, pictures, music and any other multimedia I choose to host on my media server.

 

raspberry-pi-2-pinoutmaxresdefault

There are also a number of other things that any of the Raspberry Pi family is capable of doing, including interacting with the physical world via it’s GPIO pins.  The Zero doesn’t come out of the box with the 40pin header required to use the GPIO, however it’s easily soldered onto the board.  I have a couple Pi 2’s that have temperature sensors hooked up to them and I track the temperature via MRTG graphs.  I also hope to set up an animated Christmas light display using a SainSmart 16 Channel relay board that is controlled by the Pi turning on and off each individual circuit.  It could also be used for home automation in that regard.

 

I could go on and on about all the things that these little buggers can do, but this article is focused on the Zero.  Below I’ll list some of the hardware (with prices and source) that you’ll need in order to put the Zero into service.  Add it all up and you’ll have to purchase at least another $16+ worth of hardware to really get some use out of it.  Granted I went as cheap as I could find online and I didn’t factor in any shipping or tax so your total could very well be north of $20.  For that, you can almost get a Raspberry Pi B+ that has full size HDMI, built in Ethernet and 4 full size Type A USB ports as well.  But c’mon- look how small this thing is- you can hide it in a can of Altoids and have room to spare for cripes sakes!

 

4105_large

61xpLcWy1cL._SL1500_

31+9SnMkOAL

61IVHo1bOBL._SL1001_

61+xxjf-4BL._SL1400_

 

There are a number of remote control apps that allow your phone/tablet to serve as the remote control for Kodi.  What’s really cool is that Kodi also supports the CEC (Consumer Electronics Control) standard which allows you to control some devices via the HDMI protocol.  This means that in a lot of cases, you can simply use the remote that came with your TV to navigate through Kodi without any additional hardware needed!

 

 

My car stereo runs Android, does yours?

713yuNsMiCL._SL1001_I’ve been into high end car audio for decades.  I’ve had a number of stereo systems in multiple vehicles. I spend a LOT of time on the road and music has always been a passion of mine.

 

I’ve owned a number of head units from cheap kraco single DIN cassette players to high end double DIN touchscreen navigation units.  I’ve also been a smartphone junkie for years too (I work in IT, no big shock there).  I’ve always felt that most car stereos offer a good portion of what I’m looking for, but when it comes to really customizing them they’ve always fallen short.

 

Enter the Joying JY-UQ124U Android Head Unit.  That’s right, I said Android!  This little devil is packed to the gills with features too.  Here’s a quick overview:

  • Quad Core Cortex ARM A9 RK3188 1.6GHz CPU
  • Android KitKat v4.4.4 OS
  • 1GB onboard RAM
  • 16GB NAND Flash Memory
  • 8gb Micro SD with maps pre-loaded (2x MicroSD slots- this occupies one of them)
  • 7″ 1024*600 HD resolution capacitive multi touch screen
  • GPS receiver
  • WiFi (can also tether to cellphone)
  • 3G wireless capability (hotspot sharing available)
  • Bluetooth
  • Microphone (internal AND external MIC included)
  • 2x USB “whips” for external device inputs
  • Android mirroring compatible
  • iPhone AirPlay compatible
  • Native Steering Wheel audio control compatible with most vehicles
  • DVR capabilities (dash cam functionality)
  • OBDII connectivity and software built in
  • Back up camera compatibility

That’s a high level overview, there are a LOT of features due to the fact that this unit runs android and is basically a computer.  Because of this, I wouldn’t recommend this device for someone who’s not very technically inclined.  I think it would be a little disappointing to someone who isn’t able to really get in and tweak the settings to their liking.  It helps a lot if you’ve owned an android phone or tablet in the past as the interface is exactly the same.  I recall years ago seeing a car stereo that was built on top of Linux with a small LCD display and I thought that was the COOLEST thing!  I don’t recall how much it cost but this was back in the 90’s and it was a lot more than I could afford to spend on a car stereo at the time.  Here’s a picture of one:

262516-empeg

 

So imagine my delight when I came across an Android based car stereo!  At the time, I had a Pioneer X4600-BT head unit which I had been using for about 6 months.  After about 5 months the touchscreen started flaking out and became unresponsive until it warmed up.  I was looking at a few weeks to a month or more to wait for it to be sent in to Crutchfield for repairs.  There was no way I would be able to go that long without some kind of car stereo, so I started looking for something relatively inexpensive to bridge the gap.  When I stumbled upon the Joying unit, I thought for sure it was in the 4 digit price range.  Shockingly, it was very affordable- especially considering all the functionality and quality of screen that came with it.  I wound up paying about $270 for the JY-UQ124U and was really stoked to put it in.  Installation was a bit dicey due to the number of wires, no native wiring harness plug (although they do sell them for my vehicle), and the language barrier in the very lacking wiring and installation instructions.  I had to connect a good handful of wires by hand and clipped the rest.

 

Ok- on to the review.  I’ve had it for about 2 months now and have had enough time to experience all the nuances- good and bad.  Suffice it to say I’m very pleased with what I got for my money.  I’ll break down the pro’s and con’s and then go into detail on some of the more relevant findings:

 

Pro’s

  • Display – very responsive to touch and accurate.  Colors pop and good overall resolution.
  • Built in apps (Radio, Navigation, media player, OBDII diagnostic program, etc).
  • Response time very respectable for an ARM processor and HD screen resolution.  Comparable to iPhone performance.
  • Micro SD slot for storage expansion.
  • 2x USB headers – so far I’ve been able to use a 128GB thumb drive with no problems!  Also supports plugging in a webcam for dash-cam DVR functionality.
  • GPS receiver built in.  Extremely accurate and fast- much more so than my iPhone’s GPS radio.
  • WiFi capability (you can tether it to your cellphone, a mobile puck like the Verizon MiFi, or a regular WiFi network assuming you’re in a location for long periods of time).
  • 3G dongle capability.  Requires a 3G SIM card and dongle (sold separately) but you then have in-car internet that you can share out as it’s own hot spot if you like.
  • Back up video source available even during boot process.
  • adjustable output level (can get comparable voltage to 4-5v head units with some tuning)
  • 2x MicroSD slots (one already occupied by 8gb card with pre-loaded maps)

 

Con’s:

  • Poor sound quality in radio app (other sources such as MP3 sound fine).
  • Sketchy sound quality at times (sort of like what a badly encoded or highly compressed MP3 sounds like).
  • Boot time.  It supports up to a 2 hour sleep function for a 2-3 second power up, however cold boot is about 45-60 seconds until full functionality.
  • Installation – radio dimensions not exactly U.S. Double DIN size but is close enough to work (can be a tight fit).
  • Volume function fails intermittently where volume up and down on the knob is non responsive (pushing the button still mutes and un-mutes).
  • Limited amount of memory to install apps
  • Can’t do a true reboot without setting sleep timeout to minimum, powering off the entire car and waiting 30 seconds.
  • Lack of low-pass/high pass control for front/rear and sub outputs.
  • iOS 9+ AirPlay does not work.
  • No CD/DVD capability.  Really- is that a big deal anymore?

 

As I said- overall I’m impressed and happy with this unit.  Probably the biggest quirks are the volume knob flakiness and the poor sound quality from time to time.  Honestly my gut tells me the sound quality is a questionable electronic connection inside the unit somewhere.  I only seem to notice it when I’m driving (bumps on the road) and it could be shaking something slightly loose.  I downloaded an app to do a reboot so I can at least recover volume knob functionality (thankfully I can still control the system volume from the settings app manually, but that’s definitely not a permanent solution).  I have a 5 channel amplifier hooked up to it and I really miss the ability to control what frequencies go to which speakers.  I think there’s some sort of built in low pass filter on the sub channel but the front and rear outputs are full range so I need to be careful to set the gain so my main speakers don’t blow up!

 

As far as the radio function, there is some room for improvement.  It could be my antenna but the reception on this unit is really bad.  I get static on a lot of stations where other cars get a clear signal.  The biggest drawback with the tuner however is that apparently it is routed through the audio circuitry in a different manner than the rest of the system.  Due to this, the equalizer or really any tonal control is lost.  The resulting sound quality is very poor due to a completely flat and non-adjustable source.  As I stated earlier, the rest of the audio sources seem fine- the 9 band EQ can do a nice job of shaping the sound you want with multiple saveable presets as well as pre-configured ones (bass, jazz, rap, pop, the usual suspects).

 

The built in OBDII app (interfaces with an OBDII scanner module either via bluetooth or wifi) does a capable job of reading codes and displaying real time telemetry from the car’s computer.  I personally prefer DashCommand which is a bit more “polished” and has a few more bells and whistles.  I picked up an OBDII wifi dongle and OBDII extension cord for about $20 for both.  Also, and not that this is a huge selling feature but for sure a big geek factor, is the ability to plug a webcam right into the USB port and record video to the MicroSD card or a USB thumb drive.  It will automatically continue to record in the background even while using other apps such as the radio or media player.

 

According to CarJoying (the company who sells this unit), it is supposed to be able to mirror android phones as well as iOS devices via AirPlay.  I haven’t tried an android device, but I’ve found that as of iOS 9 the AirPlay functionality seems to be broken in relation to this unit.  I was able to see the unit as an AirPlay target but was unable to ever get the display mirrored successfully.  Not a huge deal for me but still it would be nice if it worked.

 

I discovered that there are only a few actual manufacturers of these android based units (all based in China), and a large number of resellers.  Each of them offer a slightly customized version of what I got but under the covers, they’re pretty similar.  There is a whole community of android head unit owners over at the XDA-Developers website.  I’ve spent some time there and gotten the answer to a lot of my questions.  I’ve not messed around with the OS portion too much- eventually I’d like to configure the ability for a longer sleep time (12-16 hours) so when I get back in the car the next day it’s ready to go much quicker.  I would also like to be able to have the ability to remotely log in when I’m at home to tweak settings or just play around.  I have it configured to connect to my home WiFi automatically so program updates from the Google Play market can update automatically.

 

I could go on about all the little things this head unit is capable of, but suffice it to say that I’m happy overall with it and plan on keeping it.

 

 

 

 

OpenELEC FTW!!

openelec_logo_notype_512x512I’ve been playing around with something called OpenELEC.  It’s an open source media center solution based on Linux similar to Myth TV.  The ELEC part of the name stands for Embedded Linux Entertainment Center, appropriately so.  This is the framework container that provides the OS in which the actual media center software runs.

 

The media software that provides the user interface and media handling ability is called kodi.  Kodi started out as a project to provide a media center environment to the XBox.  Originally in 2002 when it was first developed, it was called XBox Media Player.  In 2004, the development team decided to rename it to XBox Media Center.  Then in 2008 it was renamed to just XBMC as it had moved on from it’s roots in the Xbox.  Shortly after being renamed XBMC, support for the XBox was dropped.  In 2014, XBMC was renamed to Kodi and they had their first release called Helix.  I won’t bore you too much more on the details or history of this media center software, you can fire up your google-fu and do just as good a job as I can.

 

So I used to have (still do actually) a Western Digital Live TV media player.  It was highly recommended from my good friend Dusty Hudson who works for Dolby Laboratories out in sunny California.  I was looking for a set top box to bring together all of the assorted media I had stored on my file server and be able to access it via the TV interface without having to have a loud bulky computer sitting in the living room like an eyesore.  I used to rock Windows 7 Media Center and that worked pretty well overall.  Still had to have the big ugly and noisy desktop computer sitting in the living room though.  This solution was rather low on the WAF (Wife Acceptance Factor) scale but it worked ok.  Once I stared to get a ton of movies though, the interface just started to choke and became pretty much unuseable.  Back to the WDTV that replaced MCE, it seemed to work pretty well- better than Media Center in a lot of ways.  I picked one up refurbished for $60 and had it for about a year.  It started to flake out on me though- it would freeze up during playback or sometimes I had to power cycle it to get it to turn on.  After dealing with this for months I started to look around for alternatives.

 

raspberry_pi_logoFast forward to today. I’ve been playing around with Raspberry Pi’s (Pi 2 and B+) lately.  Then I stumbled across this page on OpenELEC.  I don’t recall exactly how I found it, but it seemed very intriguing given that there’s a build that runs on the Raspberry Pi.  At first I thought this would be a non-starter given the relatively limited processing power of the 900MHz quad core ARM Cortex-A7 CPU and 1gb of memory.   Come to find out that the Pi 2 has built in hardware video decoding for the following codecs:

 

  • H.264 (up to High Profile) encoded videos are supported up to 1080P using hardware video decoding. Note: Hi10P will not work.
  • MPEG-4 encoded videos are supported up to 1080P using hardware video decoding. This includes XviD and recent versions on DivX (but not the older 3.xx DivX).
  • The Raspberry Pi Foundation offers additional video codec licenses for a few dollars. At the moment you can purchase MPEG-2 and VC1, both with support up to 1080P. Read below on how to enable these.
  • MJPEG, VP6, VP8 and OGG Theora are supported as GPU accelerated software decoders. These are limited to DVD resolutions.
  • Codecs without gpu support like DivX 3, msmpeg and sorenson spark will be decoded by dvdplayer on the ARM. Should work for SD resolutions.
  • DVD ISOs with menus should work fine (using dvdplayer).
  • Software DTS audio decode works well in recent builds. TrueHD audio is CPU intensive and may require overclocking.

 

Quite the little powerhouse for less than $30!  So I loaded OpenELEC on my MicroSD card, threw it in and booted it.  BAM!! right out of the box, everything booted up fine, no errors, no video or audio issues, networking, all good!  A far stretch from my experiences with Myth TV years ago.  I’ve only been running it a few days but so far there are a LOT of features and they’re extremely customizable.  There are builds for windows as well if you want to try it out without actually installing it on a Pi.  I give it a big thumbs up so far!

 

 

Raspbian findings so far

It’s been a couple weeks of playing with the Pi 2 and it’s defacto OS- raspbian.  My installation is based on the debian wheezy build which is also known as Debian 7.  I’m content for now, but would really like to find a RedHat based distribution that works as I’m much more familiar with that.  I tried Pidora but I couldn’t even get a boot screen with that image. I’m also looking into upgrading raspbian to Jessie (aka Debian 8).

 

Anyway- on to the findings.  So I had a TON of issues with something that really shouldn’t have been an issue.  I was trying to configure a static IP on my eth0 interface and for some ungodly reason it just wouldn’t take across reboots.  I finally wound up configuring the MAC address of the Pi’s NIC in my dhcp server and set the interface to DHCP.  It will always lease the same address this way but it’s a kludge and I’d like to get it working properly.  I did the same for the Ralink wifi usb adapter for the time being.  You’d think that the following config would git ‘r done but for some reason it didn’t:

 

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet static
 address 192.168.1.20
 netmask 255.255.255.0
 gateway 192.168.1.1

 

I don’t see any evidence that NetworkManager is installed in the Raspbian image I’m using so I don’t think it’s that.  If anyone has had issues like this- post a comment and let me know what you did to fix it.

 

The second thing I’ve been running into is also related to networking.  My Ralink adapter for some reason likes to disconnect every so often:

Jun 8 00:05:10 mypi kernel: [425582.545653] usb 1-1.4: USB disconnect, device number 6
Jun 8 00:05:11 mypi kernel: [425583.546048] usb 1-1.4: new high-speed USB device number 7 using dwc_otg
Jun 8 00:05:11 mypi kernel: [425583.663302] usb 1-1.4: New USB device found, idVendor=148f, idProduct=5370
Jun 8 00:05:11 mypi kernel: [425583.663320] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun 8 00:05:11 mypi kernel: [425583.663332] usb 1-1.4: Product: 802.11 n WLAN
Jun 8 00:05:11 mypi kernel: [425583.663343] usb 1-1.4: Manufacturer: Ralink
Jun 8 00:05:11 mypi kernel: [425583.663354] usb 1-1.4: SerialNumber: 1.0
Jun 8 00:05:11 mypi kernel: [425583.756056] usb 1-1.4: reset high-speed USB device number 7 using dwc_otg

 

When it does this, it drops from the wifi network and doesn’t come back unless I unplug the adapter and plug it back in, or if I reboot the Pi.  To get around this, I’ve done a few things:

  • set wireless-power to off in /etc/network/interfaces
  • created a script that checks every minute to see if wlan0 has an IP address.  If not, it downs and ups the interface.

Here’s my current interfaces file:

auto lo
iface lo inet loopback

#auto eth0
#allow-hotplug eth0
#iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa.conf
wireless-power off

 

Here’s the script I put into cron:

#!/bin/bash

datestamp=`/bin/date '+%D %T'`
result=`/sbin/ifconfig $1 | /bin/grep "inet addr:"`
logfile=/var/log/wifi/connection_status

if [ -z $1 ]
then
        echo "usage: $0 {interface}"
        exit
fi

if [ ! -z "$result" ]
then
        echo "=== [$datestamp] ===" >> $logfile
        echo "Found an IP on [$1].  No action taken." >> $logfile
        echo "===================================================================" >> $logfile
else
        echo "=== [$datestamp] ===" >> $logfile
        echo "No IP on interface [$1].  Restarting interface [$1]." >> $logfile
        echo >> $logfile
        echo "Stopping $1." >> $logfile
        /sbin/ifdown $1 &>> $logfile
        echo  >> $logfile
        echo "Starting $1." >> $logfile
        /sbin/ifup $1 &>> $logfile
        echo "===================================================================" >> $logfile
fi

 

And here’s the crontab entry I used (root crontab):

*/1 * * * * /usr/local/bin/check-wifi.sh wlan0

 

The script is a bit verbose but I used it to debug the connection so I want to know what’s going on. I’m hoping this will work cause I really like being able to stick this thing anywhere in range of the wifi signal where I can provide power.

Raspberry Pi 2B has arrived!

raspberry_pi_logoSo I finally decided to jump into the world of makers. I got me a Raspberry Pi 2 model B!  I also acquired a 16 port relay board, a 2.4″ TFT touchscreen and some jumper cables. I’m working my way around Debian linux again so have to re-remember all the old commands and file locations (hello ubuntu- I guess you were good for something other than playing around after all). I tried to find a good RedHat distribution that would run on the Pi but Pidora wouldn’t boot out of the box for me and I can’t seem to find a Fidora image to try. Regardless, it seems that most Pi users stick with the very popular debian based Raspian distro, and since I’m a noob in this area I figure it would give me the best chance of finding tutorials based on the OS I’m running.

First off- the specs. The Pi 2 model B is based on a 900MHz quad-core ARM Cortex-A7 CPU (BCM2836) with 1gb of onboard memory. It’s supposedly 6 times faster than the previous model B+ which employed the 700Mhz BCM2835 processor.  It has:

  • 4 USB ports
  • 40 GPIO pins
  • Full HDMI port
  • 10/100 Ethernet port
  • Combined 3.5mm audio jack and composite video
  • Camera interface (CSI)
  • Display interface (DSI)
  • Micro SD card slot
  • VideoCore IV 3D graphics core

It’s still a 32bit OS/CPU but is very capable of basic desktop functions including web browsing and even video gaming (raspbian ships with a Pi version of Minecraft that actually performs pretty damn good).  The coolest part is the size- it’s about as big as a deck of cards!

Pi2ModB1GB_-comp

 

I’m hoping to educate myself on the 40 pin GPIO interface that allows you to control external devices (like the 16 relay switchboard I got) to do some cool home automation.  There’s even software that allows you to do the synchronized christmas light shows.  So far, I have the OS set up to grab a fixed IP address from my router via DHCP so I can ssh to it.  Gonna try to get the display working first then we’ll see what’s next.