Quickie: Problems with the PIUART

All rights reserved to LadaAda

It’s been a while since I’ve done a quickie, but I wanted to put this out there before I forget it.

Now, I openly admit that I found this by searching for a while and am basically going to copy and paste the answer; however, I’m going to add some additional information so that when Google (or some other search engine) crawls across my website it’ll be easier for others to find this page and they won’t have to spend so much time searching.

So I got the Adafruit PiUART from Microcenter, just to pick it up and I thought it looked cute as it fit just perfectly on the Pi itself (unlike using a “traditional” USB to Serial converter).

So I followed the directions listed here, which basically show how to enable a serial console using `raspi-config`; however, when plugging it in, I got this in `dmesg`:

[121428.924972] usb 2-1.3: new full-speed USB device number 6 using xhci_hcd
[121429.033381] usb 2-1.3: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
[121429.033386] usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[121429.033390] usb 2-1.3: Product: CP2104 USB to UART Bridge Controller
[121429.033392] usb 2-1.3: Manufacturer: Silicon Labs
[121429.033395] usb 2-1.3: SerialNumber: 01A0FEC4
[121429.640723] usbcore: registered new interface driver cp210x
[121429.640737] usbserial: USB Serial support registered for cp210x
[121429.640791] cp210x 2-1.3:1.0: cp210x converter detected
[121429.645560] usb 2-1.3: cp210x converter now attached to ttyUSB2
[121429.768218] usb 2-1.3: usbfs: interface 0 claimed by cp210x while 'brltty' sets config #1
[121429.769908] cp210x ttyUSB2: cp210x converter now disconnected from ttyUSB2
[121429.770030] cp210x 2-1.3:1.0: device disconnected
[121430.260637] input: BRLTTY 6.0 Linux Screen Driver Keyboard as /devices/virtual/input/input19
[121770.452594] usb 2-1.3: USB disconnect, device number 6
[121772.725940] usb 2-1.3: new full-speed USB device number 7 using xhci_hcd
[121772.838333] usb 2-1.3: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
[121772.838339] usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[121772.838342] usb 2-1.3: Product: CP2104 USB to UART Bridge Controller
[121772.838344] usb 2-1.3: Manufacturer: Silicon Labs
[121772.838347] usb 2-1.3: SerialNumber: 01A0FEC4
[121772.841427] cp210x 2-1.3:1.0: cp210x converter detected
[121772.846646] usb 2-1.3: cp210x converter now attached to ttyUSB2
[121773.460377] usb 2-1.3: usbfs: interface 0 claimed by cp210x while 'brltty' sets config #1
[121773.461454] cp210x ttyUSB2: cp210x converter now disconnected from ttyUSB2
[121773.461551] cp210x 2-1.3:1.0: device disconnected
[121773.955520] input: BRLTTY 6.0 Linux Screen Driver Keyboard as /devices/virtual/input/input20

So as we can see, it starts to register the device as /dev/ttyUSB2, but then `brltty` takes over and says “thanks, but I’ll take it from here” and when I try to connect to it, the device is no longer there.

First off, what is brltty? Well it’s the Braille tty daemon, simply put. I didn’t put too much stock into trying to figuring it out; however, I knew that was the problem.

Adafruit’s directions doesn’t give any troubleshooting advice. My first guess was to try and search currently running daemons using systemctl and stop the daemons. I tried that, but systemctl wouldn’t let me stop them…something about them being a prereq to something (IIRC). So with that not working I had to search until I came across an OpenSuSE Forum post.

Solution

Basically, I was able to solve it by just removing brltty. Now if you need Braille support, then this obviously won’t work for you, but I’m (relatively) able-bodied, so I had no problems just chucking it.

su
zypper rm brltty brltty-driver-at-spi2 brltty-driver-brlapi brltty-driver-espeak brltty-driver-speech-dispatcher brltty-driver-xwindow brltty-lang

Now, for me it said there was some errors and to check with `zypper ps`, so I did and I shut down all of the brltty instances:


zypper ps
systemctl stop brltty@

After doing that, unplugging and replugging the device back in, I was successfully able to connect using picocom (my preferred serial terminal emulator). The baud speed is 11500, but you can get that from the Adafruit docs.

Now, I’m using it on a Pi0W, so using a serial console doesn’t make too much sense, since I can just ssh over Wi-Fi, but that’s a different story. 🙂

Posted in Computer Science, Engineering | Tagged , , , | Leave a comment

Introduction To Apache Portable Runtime (APR) for C++

So this is going to be an introduction to working with apr using c++ for command line argument processing.

This assumes that you have some basic knowledge of C++. If you want to just jump into it, then click here I also put all of my code on GitHub if you really want to just see how to do it quickly.

Introduction

Let’s jump into it with an example C++ program:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
  cout << "Hello World\n";
}

Now, this should be a very simple program to understand. We simply print "Hello World" to the screen.

I'm sure you're familiar with adding the int argc and char *argv[] in your main implementation. You probably know that argc stands for the total amount of command line arguments (including the program name). Likewise, argv is a two dimensional array containing the corresponding values.

Let's go ahead and print those:

#include <iostream>
using namespace std;

int main(int argc; char *argv[])
{
  for(int x = 0; x < argc; x++)
  {
    cout << argv[x] << endl;
  }
}

Now if we compile and run our program, like so, we should see output as follows:

./a.out 1 2 3 4 5
./a.out
1
2
3
4
5

Of course, you could use some if statements to parse and handle your command line options, but that is complex and hard.

Let's use a library! Now, if you're on Linux, or some other OS that has POSIX libraries, then you have getopt.h.

This is an older tool, but it's super useful. Let's say that we have a program that needs the following:

  1. -h -- will display help info
  2. -v -- will display version info
  3. -n VALUE -- will take in a name and requires a value
  4. -o [VALUE] -- will take in a file name and is optional

Let's write the code first and break it down:

#include <unistd.h>
#include <iostream>
#include <string>

#define VERSION_INFO "0.0.1"

using namespace std;

void show_help(char *prog_name)
{
  cout << prog_name << endl;
  cout << "-h\tDisplay this help message and exit\n";
  cout << "-v\tDisplay version info and exit\n";
  cout << "-o[VALUE]\tAn output file\n";
  cout << "-n VALUE\tA name\n"; 
  exit(EXIT_SUCCESS);
}

void show_version()
{
  cout << VERSION_INFO << endl;
  exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
 char opt;
 
 bool have_o = false, have_n = false;
 string o_value, n_value;

 while ((opt = getopt(argc, argv, "hvn:o::")) != -1)
 {
     switch (opt) 
     {
       case 'h':
         show_help(argv[0]);
         break;
       case 'v':
         show_version();
         break;
       case 'o':
         have_o = true;
         if(optarg)
         {
           o_value = optarg;
         }
         break;
       case 'n':
         if(optarg)
         {
           have_n = true;
           n_value = optarg;
         }
         else
         {
           cerr << "No argument for -n!";
           exit(EXIT_FAILURE);
         }
         break;
     }
 }

 if(have_o)
 {
   cout << "O's value " << o_value << endl;
 }
 if(have_n)
 {
   cout << "N's value " << n_value << endl;
 }
 return EXIT_SUCCESS;
}

Let's run it!

./a.out -h
./a.out
-h	Display this help message and exit
-v	Display version info and exit
-o[VALUE]	An output file
-n VALUE	A name
./a.out -v
0.0.1
./a.out -n ceneblock
N's value ceneblock
./a.out -o
O's value 
./a.out -ofile
O's value file

Okay, so we can see that it works! Let's look at the most important part of the code:

 char opt;
 
 bool have_o = false, have_n = false;
 string o_value, n_value;

 while ((opt = getopt(argc, argv, "hvn:o::")) != -1)

getopt() takes in int argc, char **argv, and char *optstring.

It's the optstring that's important. It's a sequence of characters that for each letter, opt is set accordingly.

You'll also see that the n has a : after it. This means that there is a required argument. See what happens if you run the program without it!

After that, you'll see o has two : after it. This means that it's optional.

This is fine and great, but what if you want to write your program and have it compile on Windows or an OS without POSIX? Well, you could port POSIX (use Cygwin or MinGW for Windows) to your OS or you could use Apache's Portable Runtime!

Installing

I'm on OpenSuSE Linux and it came installed by default, but for other distro's searching for apr-devel .

For Windows, here is Apache's guide.

I'm going to assume that you can figure out how to install apr and link it. This is article is mostly to show how easy it is to code.

API

Here is the API. Now just giving it to you wouldn't be too helpful, but it's important to know where to get info.

If we click on any of the functions or data types, then we can see more info about them. Let's take a look at apr_status_t apr_getopt (apr_getopt_t *os, const char *opts, char *option_ch, const char **option_arg)

We can see that we need to provide an apr_getopt_t. Well, what exactly is that?

From that link we can see it is:

Structure to store command line argument information.

Luckily, we don't need to fill this out manually, but we do need it to have valid data, from that link, we need to call:

apr_status_t apr_getopt_init(apr_getopt_t **os, apr_pool_t *cont, int argc,const char argv)

Now here, the apt_getopt_t is going to be our return type. So we'll want to declare it:

apt_getopt_t *opt;

Next what is this apt_pool_t? Well, it's a fundamental data type for apr. You can read about related functions from that link, but really, we need to do the following:

apr_status_t rv; ///the return value datatype.
apr_pool_t *pool;
apr_pool_create(&pool, NULL);

And just like that, we've created a new memory pool. Don't worry too much about it.

Something about APR is that it needs a special function call before we do anything. This call is apr_status_t apr_initialize(void).

So right after the bracket in main, let's call it (don't worry, I'll summarize with final code at the end).

int main(int argc, char *argv[])
{
  apt_initialize();

Likewise, we need to call a special terminator before quitting:

 apr_terminate();
 return EXIT_SUCCESS;
}

Okay, now that is over, let's jump back to apr_getopt_init, the next options are obvious, argc and argv.

So at this point, we've doing our initalization, memory pool allocation, and getopt_t initalization. Now we can get to our actual apt_getopt call.

If we look at it, it is actually very similar to our POSIX getopt:

opts A string of characters that are acceptable options to the program. Characters followed by ":" are required to have an option associated

So let's copy our POSIX optstring in and see what happens!

Here is our entire code:

#include <apr_general.h>
#include <apr_getopt.h>
#include <iostream>
#include <string>

#define VERSION_INFO "0.0.1"

using namespace std;

void show_help(char *prog_name)
{
  cout << prog_name << endl;
  cout << "-h\tDisplay this help message and exit\n";
  cout << "-v\tDisplay version info and exit\n";
  cout << "-o[VALUE]\tAn output file\n";
  cout << "-n VALUE\tA name\n"; 
  exit(EXIT_SUCCESS);
}

void show_version()
{
  cout << VERSION_INFO << endl;
  exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
    apr_initialize();

    apr_status_t rv;
    apr_getopt_t *opt;
    apr_pool_t *pool;
   
    char optch;
    const char *optarg;
 
    bool have_o = false, have_n = false;
    string o_value, n_value;
 
    rv = apr_pool_create(&pool, NULL);
    if(rv != APR_SUCCESS)
    {
      cerr << "Error in apr_pool_create\n";
    }

    rv = apr_getopt_init(&opt, pool, argc, argv);
    if(rv != APR_SUCCESS)
    {
      cerr << "Error in apt_getopt_init\n";
    }

    while ((rv = apr_getopt(opt, "hvn:o::", &optch, &optarg)) == APR_SUCCESS) 
    {
     switch (optch) {
       case 'h':
         show_help(argv[0]);
         break;
       case 'v':
         show_version();
         break;
       case 'o':
         have_o = true;
         if(optarg)
         {
           o_value = optarg;
         }
         break;
       case 'n':
         if(optarg)
         {
           have_n = true;
           n_value = optarg;
         }
         else
         {
           cerr << "No argument for -n!";
           exit(EXIT_FAILURE);
         }
         break;
      }
    }
    if (rv != APR_EOF) {
        printf("bad options\n");
    }

    if(have_o)
   {
     cout << "O's value " << o_value << endl;
   }
   if(have_n)
   {
     cout << "N's value " << n_value << endl;
   }

    apr_terminate();
    return EXIT_SUCCESS;
}

Now how in the world do we compile this? To be honest, I don't know! However, there is a helper program to help us out!

apr-1-config 
Usage: apr-1-config [OPTION]

Known values for OPTION are:
  --prefix[=DIR]    change prefix to DIR
  --bindir          print location where binaries are installed
  --includedir      print location where headers are installed
  --cc              print C compiler name
  --cpp             print C preprocessor name and any required options
  --cflags          print C compiler flags
  --cppflags        print C preprocessor flags
  --includes        print include information
  --ldflags         print linker flags
  --libs            print additional libraries to link against
  --srcdir          print APR source directory
  --installbuilddir print APR build helper directory
  --link-ld         print link switch(es) for linking to APR
  --link-libtool    print the libtool inputs for linking to APR
  --shlib-path-var  print the name of the shared library path env var
  --apr-la-file     print the path to the .la file, if available
  --apr-so-ext      print the extensions of shared objects on this platform
  --apr-lib-target  print the libtool target information
  --apr-libtool     print the path to APR's libtool
  --version         print the APR's version as a dotted triple
  --help            print this help

When linking with libtool, an application should do something like:
  APR_LIBS="`apr-1-config --link-libtool --libs`"
or when linking directly:
  APR_LIBS="`apr-1-config --link-ld --libs`"

An application should use the results of --cflags, --cppflags, --includes,
and --ldflags in their build process.

As it ays at the bottom, we need:

  • --cppflags
  • --include
  • --ldflags

For me, the results are as follows:

apr-1-config --cppflags --includes --ldflags
 -DLINUX -D_REENTRANT -D_GNU_SOURCE -I/usr/include/apr-1

So I'll compile with those options:

g++ apr.cpp -DLINUX -D_REENTRANT -D_GNU_SOURCE -I/usr/include/apr-1

Now, let's test it like we did before:

./a.out -h
./a.out
-h	Display this help message and exit
-v	Display version info and exit
-o[VALUE]	An output file
-n VALUE	A name
./a.out -v
0.0.1
./a.out -n ceneblock
N's value ceneblock
./a.out -ofile
O's value file
./a.out -o
a.out: option requires an argument -- o
bad options

Uh oh! Despite our o::, we aren't able to have our optional argument like our original requirements are!

Is apr not a good solution?

Well....no. apr is a good solution, it's that I lied to you earlier. the o:: is actually a GNU extension. If we really want optional arguments, then we'll need to use getopt_long.

That, for right now, is a story for another day. This should be enough to at least get you started with apr. 😉

All code and a makefile is here

Posted in Computer Science | Tagged , , , , , , | Leave a comment

Driving a 7-segment Display with a Shift Register (74HC595)

I had a post a while back about driving a 7-segment display with an Arduino. Well, as you may recall, that took a lot of pins, 8 in fact.

What if we could reduce that by 3? What if we could only use 3?

Well, let’s introduce the shift register. This is a device which can take serial I\O and convert it into parallel.

It has two clocks on it one that reads in data and the other that shifts it out.

We have an output enable, data in, and data clear line as well.

First things first, let’s look at the datasheet.

Here is the pinout:

  • QA — QH are the outputs. In our analogy, think of having a birds eye view of our entire assembly line. We can see if there are products at any location at the same time.
  • SR — this is our input. So this is what we would place next on the assembly line.
  • OE’ — This is to say if we want to view our output on QA — QH. Two things, one is the bar (or as I’ve typed a tick or prime mark), this means logical NOT. So if you do want to view the output, then you set OE to LOW, and when you don’t, you set it to HIGH.
  • SRCLR’ — Likewise, with this tick mark, when we set this pin to low, the entire register gets cleared. All values are set back to 0. In our assembly line, this would be like flipping the entire table over.

Here is a timing diagram:

This is VERY important as it tells us what’s going on.

Let’s explain this before we get too far.

The easiest is the Output Enable (OE). As you can see, when OE’ is HIGH, the output lines (QA — QH) are in an unknown state.

Likewise, we can see the output lines go to LOW when SRCLR’ is HIGH.

Since QA — QH are outputs are low, we won’t worry about them too much, we just need to observe them along the diagram.

As we can see, the SRCLK goes up and down and the RCLK goes down and up in opposite directions. We’ll go further into that later on, but for right now, just notice that that are out of phase meaning that they do not line up. In this case, they are 180° out of phase.

Now let’s look at our SER line and our SRCLK. Notice that When SER is high and when SRCLK is high, then the QA goes high! Likewise, when SER is low.

To better understand this, take a look at Table 1. You can see arrows pointing up and down. These represent the clock phases, a raising edge and a falling edge depending on which way the arrow is pointing.

Let’s build a circuit finally!

Here is our circuit, now it looks complicated, but as we can see, it takes up less pins on the Arduino.

Here is our code:


#define SER 2
#define OE 3
#define RCLK 4
#define SRCLK 5
#define SRCLR 6

void setup() {
// put your setup code here, to run once:

pinMode(SER, OUTPUT);
pinMode(OE, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
pinMode(SRCLR, OUTPUT);

//Clear everything first:
digitalWrite(SRCLR, LOW);
digitalWrite(SRCLR, HIGH);

//Turn off the output
digitalWrite(OE, HIGH);

//Now, since we're using a common annode 7-segment,
//everything will be reversed, so a LOW will mean a
//segment is on.

//DP off
digitalWrite(SER, HIGH);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//G on
digitalWrite(SER, LOW);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//F on
digitalWrite(SER, LOW);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//E off
digitalWrite(SER, HIGH);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//D off
digitalWrite(SER, HIGH);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//C On
digitalWrite(SER, LOW);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//B On
digitalWrite(SER, LOW);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

//A Off
digitalWrite(SER, HIGH);
digitalWrite(SRCLK, LOW);
digitalWrite(SRCLK, HIGH);

//Shift to the output register
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);

digitalWrite(OE, LOW);

}

void loop() {
// put your main code here, to run repeatedly:

}

If you build, compile, and run this, then you’ll see the number 4 is displayed.

If you look, the first bit of data is our decimal point (DP), and we shift data to the left so that our last data out is our A segment. Now, go ahead and modify this so that we only have one DP on and everything else is off. Now, add an additional SRCLK and RCLK increment. You’ll see that all the segments are off! This process of data movement, where the first piece of data in becomes the first piece of data out (First In First Out\FIFO) is called a queue. Now, for international readers, you’re already familiar with this term, but for my fellow Americans, this is a line. The first person in line is the first person leaves.

You can now play with this to create a 0 — 9 counter. As a hint though, you’ll want to put a delay(####) where #### is a number (1000 = 1 second) so you can watch the number increment.

That’s all for now.

Posted in Engineering | Tagged , , , , | Leave a comment

2019/02/03 Updates!

It’s been a while and boy does the new WordPress layout stinks (v5). It looks like it was designed for mobile interfaces…

Anyway, there are some weird things going on with the site, as some of you may have noticed weird timeouts. If I have time, I’ll look into those.

I do have a lot of stuff going on and I’ll hopefully have a new post somewhat soon. I have some pics from NYC to post as well as a tech project. Here is a sneak peek.

Posted in Announcements | Leave a comment

Reading analog values over I2C

So I’m back again with another I2C device made by NXP. My last one did I2C to SPI, but we’re here to do ADC.

Now, if you’re the average Arduino user, then you have 6 ADC ports on your Uno, so why would you need any more? Well, you probably don’t, but if you’re using an ESP8266, then the onboard ADC is kinda garbage as it only tolerates values up to 1V. For some devices, this may not work as they require or output values greater than that.

I’ll be using the NXP PCF8951. A quick search looks like it can be purchased in DIP form, but I’m using a SO-16 (SMD). From the datasheet, we have the following pinouts:

If you’re familiar with any I2C device, then a lot of these pins should look familiar:

  • The A0-A2 lines are to determine the address (it starts at 0x48 – 0x4F for Arduino).
  • Vss goes to GND and Vdd to +5v.
  • SDA goes to the SDA pin on the Arduino, and likewise for SCL.

For this example, we’re going bring all of the address lines to GND. Vref is pulled to Vdd, but this isn’t needed for this example as this will be ADC, but that’d be your max output value when converting a digital value to analog. The same goes for AGND, except this will be the corresponding GND (useful if you’re using this with a separate and unrelated GND).

EXT and OSC relates to using an oscillator. The datasheet says:

8.6 Oscillator
An on-chip oscillator generates the clock signal required for the A/D conversion cycle and for refreshing the auto-zeroed buffer amplifier. When using this oscillator the EXT pin must be connected to VSS. The oscillator frequency is available at the OSC pin. If the EXT pin is connected to VDD, the oscillator output OSC is switched to a high-impedance state allowing to feed an external clock signal to OSC.

For what we’re doing, we’ll just set EXT to low.

We’ll put two pull-up resistors on the SDA and SCL lines (as per usual). We’ll tie our non-used analog lines to GND (A1-A3).

Finally, for our actual device, we’ll connect our Analog Out to A0. In my case I’m using a cheap moisture meter (FC-28, for those playing alone at home), but you can use whatever you want. I’ve left it purposefully ambiguous in the circuit diagram.

Speaking of witch, if you have everything set up correctly, your breadboard should look like this:

Time to code!

I’m going to assume that you have the prerequisite libraries and such and don’t need an explanation on them. I’ll include that stuff in my code, but I won’t go in depth.

If we look at Figure 18 in the datasheet…hold on, I can’t harp on it how much you NEED to read the datasheet! Take my examples and use them to learn how to read the datasheet.

Anyway, if we look at Figure 18, we can figure out what commands we need to read from different values (or write them):

Since we just want to read from A0 on the chip, we’ll write 0x00 to the device from our Arduino. If you want to do A1, then you’d send 0x01, and so on. Now if all four of your analog ports have devices you want to read from, you can use the auto-increment flag and send 0x05 and read multiple times.

Anyway, here is the code as promised. It’s extremely short. As you run this, you’ll notice your max values might seem strange. For the answer why, you can easily find that in the datasheet. 😉


#include "Wire.h"
#define PCF8591 0x48

void setup()
{
Wire.begin();
Serial.begin(9600);
}

void loop()
{
int value = 0
Wire.beginTransmission(PCF8591);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(PCF8591, 1);

value=Wire.read();

Serial.print(value);
Serial.println();

}

Posted in Engineering | Tagged , , , , | Leave a comment

TV Time! On the go! Part 1

Not too long ago, YouTube recommended this video to me about hacking a Sony Watchman:

I thought that was pretty neat and wondered what I could do with one, so I was able to pick one up for like $20, but if I just redid the experiment shown, then that would be boring and we may run out of those in the future. So instead, I purchased a Citizen Compact Pocket B&W LCD TV 06-TA (Which apparently cost $88!).

As we open this, we’ll see a TV tuner in there that we’ll want to remove. It is 10 pins and a pain in the butt to remove. I’ve highlighted the pins that connect to the tuner.

Now, with that removed, we can start looking at the good stuff! As mentioned in the above video, we have a MS1348FP on our board. Now, I didn’t go yanking it away, but I did experiment as shown below:

Now that we know this is the chip, we can remove it and (ab)use the datasheet and it’s pins for a composite out.

However, after removing it and hooking everything up, I found that composite video out isn’t quite right and has sync issues, so I’m going to have to come back with a follow up. 🙁

Posted in Engineering | Tagged , , , , | Leave a comment

Sennheiser HD 58X Jubilee Review via @Massdrop

Photo by grizzlybeast on Head Fi

Thanks to @PhillyD, I was told of a pair of Sennheiser headphones was available on Massdrop. They just came in and I thought I’d give my initial thoughts.

Now, if you want the fancy technical specs, then please see Head-Fi’s forums for more details. I’m going to be giving a light overview.

Appearance

First off, let’s look at appearance. These have a very “studio monitor” type look to them and certainly look more professional than say a pair of Beats by Dre. They have velvet cups which feel amazing on the ear. This is in comparison to leatherette on a lot of other earphones. That said, I expect them to get dirty quickly as a result of wear and use. If you’ve ever owned velvet anything, then you know that getting a stain in it is pretty much game over. The cans completely cover my ear and the top band isn’t that tight (helpful if you have a widehead or just don’t like your ears being squeezed). The top foam is in two parts, which is what it is.

Feel

How about feel? They feel like plastic. No way around that. These aren’t Meze’s. I feel like I could easily snap the plastic on the can near the cup, which might cause issues if you toss them in a backpack. It doesn’t feel fragile per se, but I think if I drop it a few times, then it’ll crack. The straps are steel. The edges could be smoother, but they aren’t sharp by any means. The included cable is heavy! I don’t see this as a bad thing as I’m sure we all have cheap earbuds where the speakers are good, but the cable breaks apart. The left and right lines have a diameter of 3mm (compared to the 1mm thickness on a pair of skullcandy ink’d). The headband feels sturdier, but I didn’t feel comfortable flexing it that much.

Sound

Finally, sound! Now I first have to admit my bias. I am not a fan of head massages (heavy bass). I feel like bass is easy to do and I look down on Beats by Dre for being glorified head massagers. I want to hear my vocalists and high range. Depending on who you ask, you might want to “burn in” your headphones (i.e. let them run with music playing for so many hours), but since I just got them, I haven’t gotten a chance to do that. I am listening to flac and wav files going through my desktops onboard soundcard (Audio device: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA) (rev 40)) without an amp or anything special:

Classical

How does Classical sound?

  1. CPE Bach’s Flue Concertos. It is a little heavy in the bass. I can hear the flutes, but they don’t stand out as much as I’d like.
  2. Likewise on Vivaldi’s The Storm Movement II.
  3. Verdi’s Requiem — Libre Me. Angela Gheorghiu’s vocals don’t stand out in Verdi’s Requiem and the midranges on sound muddled.
  4. Gregorio Allegri – Miserere mei, Deus. Quiet and that falsetto doesn’t ring like it should.
  5. Sarah Brightman — Pie Jesu. My last test is for the living angel Sarah Brightman’s Pie Jesu and I just don’t like the sound.

Jazz

What about Jazz? Well, I don’t own too many Jazz albums, but I feel it’s important to test.

  1. De-Phazz — Cut the Jazz. Sounds good, but a little too bass-y for me. Vocals sound like they should.
  2. Gotan Project — Celos. This is a beautiful song and really shows how good of a genre this can be. Again, heavy on bass, but warm vocals
  3. Lorenzo Trujillo & The Soul Circus. Could be brighter. Period.

Metal

Metal is a lovely genre because of how technical pieces can get. It tends to incorporate elements of classical which is always nice.

  1. Muse — Reapers. Snare and high hat sound like they are in a different room in the beginning. Vocals are fine.
  2. Deftones — Adrenaline Album. It’s okay. Nothing to write home about.
  3. Dream Theater — The Glass Prision. It’s okay.
  4. Dream Theater — The Dance of Eternity. I had to do this, because I’d get raked across the coals for not doing this Dream Theater classic. I was mostly interested in Ruddess’s Keyboard Solo. It didn’t pop like I wanted it to.
  5. Dan Mumm — Toccata and Fuge in D Minor. Guitar is muted by background instruments.

Punk

Punk is one of the genres that I listen to the most, so I better get some enjoyment out of here. 🙂

  1. Armor for Sleep — Car Underwater. Sounds right. Can’t complain.
  2. Chidos — Hey Zeus! The Dungeon. Everything is covered by the drums.
  3. Forgive Durden — Il Tango Della Signora Francesco di Bartolommeo di Zanobi Del Giocondo. Need more vocals.
  4. Fall Out Boy — West Coast Smoker. Patrick Stump’s voice seems to be in the sweet spot of these earphones.
  5. Paramore — crushcrushcrush. Haley sounds good, but the bass needs to drop.
  6. The Cab — One of THOSE Nights. The guitar stands out in an annoying way with it’s simple riff. This is something that I’ve never noticed in the song before.
  7. The Dear Hunter — The Color Spectrum Black EP. I heard some parts of the song that I’ve never heard before, so that’s neat!
  8. Jonny Craig — What I Would Give To Be An Australian. Someone who is in my vocal range. Good mixing by the studio and it is replicated here

Others

Any other music that I thought might be worth a listening to.

  1. Campo — Tuve Sol. Guitar strums sound very nice.
  2. The Reign of Kindo — Out of Sight Out of Mind. This is always awkward as you have a better sound quality on their YouTube Channel, so I decided to go with that instead of my own copy. A lot of the instrumentation can easily be heard and what I call a “Wall of Sound” isn’t as strong on a pair of modified headphones. Note, what I call “Wall of Sound” is different than the traditional definition, so sorry Beatles fans.
  3. Sergei Tumas — Libertango. The trumpet sounds nice and so does the synth.
  4. Josh Ritter — Another New World. The French Horns sound amazing! He voice stands out (like it should..)

Verdict

At $150, this is a good pair of earphones; however, I’ll certainly be getting some polyester filling to dampen the bass a lot. This is hands down my biggest complaint about it. They are a steal at sub $100, so check on eBay for second hand. They are leagues above what most people use, so my criticisms are not from the sub $50 range (most of what you find at WalMart or Target), so keep that in mind when reflecting on this review.

You can purchase them here (AFFILIATE LINK!)

Posted in Reviews | Tagged , , , , | Leave a comment

Catching up with the P8284A (quickie)

I have a few secret projects I’ve been working on, but a quick thing that I can show is how to make a working clock with a P8284A (Here is the datasheet)

This chip was used for generating the clock for 8086s and 8088s, so it’s kind of a big deal. The unfortunate thing is, they are hard to find nowadays.

If you are able to get your hands on one and want a quick and dirty way to set up one, then use the layout below:

or use this pdf.

Now wait! I hear you exclaim! You’re using a 24MHz to drive an 8088!? Those things can only handle a max of 8MHz and you’re supplying a crystal 3x as much!

Yes, this is true, but the P8284 outputs a signal 1/3 that speed. It’s wave output is a little weird too. Take a look:

Now I did make a board layout for it as shown below. The first image is of the front:

And here is the back:

I haven’t tested it, but I’m gathering a batch of boards to ship off to JLCPCB for further testing.

The giant circle in the middle is a mounting hole which should fit a m3 screw, but it might be too tight, we’ll see.

I won’t go in to too much detail about the various values I chose, but there are some “optional” parts (i.e. the capacitors). I don’t recommend skipping the timing (electrolyte) and bypass (ceramic) cap. You can get some more information on that here and other videos:

So maybe if you’re fixing your old IBM AT or IBM PS/2, then this might help 🙂

Posted in Engineering | Tagged , , , , , , | Leave a comment

Arduino I2C to SPI with SC18IS602B

I’m going to be doing some neat things with an STM32F030 and since it’s a limited pin number, I want to maximize my pins and I want to make it somewhat expandable\hackable, so because of this, almost everything is going to need to go across i2c; however, I have LCD screens that work across SPI and likewise SD cards can use a SPI interface, so I need a way to access those over SPI.

Enter the SC18IS602B! A relatively cheap I2C to SPI adapter and super easy to work with.

Setup

For our SPI device, I’m using Sparkfun’s Serial 7-Segment Display because of how basic it is. Just send it data and it’ll spit it on the screen.

Once you have it soldered to a breakout board, here is the layout I’ve gone with:

You’ll notice three lines going from 14-16 to ground. These are the address lines (A0 – A2 respectively). If you look in the datasheet (linked above) on Figure 4 we can configure the address for our device. Now if you’re new to I2C, then this is a very common feature of I2C devices.

For us Arduino users, we ignore the RW bit as that’s automatically taken care of by the Wire library, so all we need to do is look at the actual numbers, in our case, we are dealing with 0x28. So we would use

Wire.beginTransmission(0x28);

when we want to talk to that device. Of course, you can change the address lines yourself and change your corresponding variables. If you can’t figure it out, then the Arduino I2C Scanner Sketch is super useful.

First attempt

To talk to a specific SPI slave, then we simply do

Wire.beginTransmission(0x28);
Wire.write(0x0X);
Wire.write(DATA);
Wire.endTransmission();

Where X = the SPI slave number + 1 (yes, SPI slave 0 you would do Wire.write(0x01), see Table 4 for more information).

So, let’s write ‘hiEe’ to the display:

#include <Wire.h>

#define TWI_ADDR 0x28
#define RESET_SEG 7
#define RESET_TWI 8
void setup() {
// put your setup code here, to run once:

pinMode(RESET_SEG, OUTPUT);
pinMode(RESET_TWI, OUTPUT);
digitalWrite(RESET_SEG, HIGH);
digitalWrite(RESET_SEG, LOW);
delay(50);
digitalWrite(RESET_SEG, HIGH);

digitalWrite(RESET_TWI, HIGH);
delay(100);
digitalWrite(RESET_TWI, LOW);
delay(100);
digitalWrite(RESET_TWI, HIGH);
delay(1000);
Wire.begin();

}

void loop() {
// put your main code here, to run repeatedly:
Wire.beginTransmission(TWI_ADDR);
Wire.write(0x01);
Wire.write('v');
Wire.write('h');
Wire.write('i');
Wire.write('E');
Wire.write('e');
Wire.endTransmission();
delay(500);
}

Diagnosing the problem

We upload this and…..we get garbage!? Did we do something wrong? Is the chip broken? What’s going on?

We’ll let’s debug this using an oscilloscope. I’m using anOpenScope MZ and by probing the SPI Clock (Blue) and MOSI (Orange), I get this wave form:

Here, we can see our v and h being sent correctly, but we the screen is garbage…so what’s going on?

Well, sadly, the SparkFun datasheet doesn’t say this, but our problem is that we’re going too fast for the display to keep up with. So we must slow down our chip!

How though?

Fixing the problem

Well, time to turn to the Datasheet!

Section 7.5.1 gives detail on how to configure the SPI interface.

By default register 0xF0 is set to all zeros. If we look at bits 0 and 1, we can set the clock!

To do this, we’ll add the following:


Wire.beginTransmission(0x28);
Wire.write(0xF0);
Wire.write(0x03); //set our SPI clock to the slowest
Wire.endTransmission();

With this change and after we reupload, things should look correct, although, you may still see a flicker, but that can be adjusted to your own needs.

Now, I don’t know how a beginner is supposed to figure this out on their own (especially if they don’t have an oscilloscope), but I hope that this helps someone out.

Final Code

#include <Wire.h>

#define TWI_ADDR 0x28
#define RESET_SEG 7
#define RESET_TWI 8
void setup() {
// put your setup code here, to run once:

pinMode(RESET_SEG, OUTPUT);
pinMode(RESET_TWI, OUTPUT);
digitalWrite(RESET_SEG, HIGH);
digitalWrite(RESET_SEG, LOW);
delay(50);
digitalWrite(RESET_SEG, HIGH);

digitalWrite(RESET_TWI, HIGH);
delay(100);
digitalWrite(RESET_TWI, LOW);
delay(100);
digitalWrite(RESET_TWI, HIGH);
delay(1000);
Wire.begin();

//Slow down our SPI bus
Wire.beginTransmission(TWI_ADDR);
Wire.write(0xF0);
Wire.write(0x03);
Wire.endTransmission();

}

void loop() {
// put your main code here, to run repeatedly:
Wire.beginTransmission(TWI_ADDR);
Wire.write(0x01);
Wire.write('v');
Wire.write('h');
Wire.write('i');
Wire.write('E');
Wire.write('e');
Wire.endTransmission();
delay(500);
}

Posted in Engineering | Tagged , , , | Leave a comment

Foie Gras Mr. President?

Today was the day that many of us Americans had been waiting for: the big US-Russia summit in Helsinki, Finland.

This came off of a gaffe filled week while in the UK where the President insulted U.K. Prime Minister Theresa May in an interview with the Sun Newspaper, where he bashed her Brexit plan, encouraged Boris Johnson to be Prime Minister (although he didn’t say he should replace Ms. May), and said that the UK was in turmoil.

This comes after a tension filled NATO summit. Where he called on countries to pay more into their defense (which is fair), but wrongly stated that the US pays in excess 4%. He also stated that Germany is under control of Russia over the Nord Stream 2 pipeline, which Russia has turned off the gas to Ukraine.

The day before the meeting, President Trump sent out this tweet (which will play an important part later):

In today’s event, the president had a private meeting with Premier President Putin that lead to a press conference. In it, he took the position of Mr. Putin that Russia had nothing to do with the 2016 election meddling, contrary to what US intelligence says. Quoting:

REPORTER, AP: President Trump, you first. Just now, President Putin denied having anything to do with the election interference in 2016. Every U.S. intelligence agency has concluded that Russia did. My first question for you sir is, who do you believe? My second question is would you now, with the whole world watching, tell President Putin, would you denounce what happened in 2016 and would you want him to never do it again?

TRUMP: So let me just say that we have two thoughts. You have groups that are wondering why the FBI never took the server. Why haven’t they taken the server? Why was the FBI told to leave the office of the Democratic National Committee?

I’ve been wondering that. I’ve been asking that for months and months and I’ve been tweeting it out and calling it out on social media. Where is the server? I want to know where is the server and what is the server saying?

With that being said, all I can do is ask the question.

My people came to me, Dan Coates, came to me and some others they said they think it’s Russia. I have President Putin. He just said it’s not Russia.

I will say this: I don’t see any reason why it would be. But I really do want to see the server but I have, I have confidence in both parties.

I really believe that this will probably go on for a while but I don’t think it can go on without finding out what happened to the server. What happened to the servers of the Pakistani gentleman that worked on the DNC?

Where are those servers? They’re missing. Where are they? What happened to Hillary Clinton’s emails? 33,000 emails gone, just gone. I think in Russia they wouldn’t be gone so easily.

I think it’s a disgrace that we can’t get Hillary Clinton’s thirty three thousand e-mails.

I have great confidence in my intelligence people but I will tell you that President Putin was extremely strong and powerful in his denial today and what he did is an incredible offer.

President Trump spent more time focusing on attacking the DNC and Hillary Clinton than squaring up with Putin about what they did.

After the feedback the President tried to do some damage control with the following tweet:

After watching this, I felt genuinely upset and saddened by the actions the president took. To no surprise, Democrats took an attack at the President, which Chuck Schumer saying:

However, Republicans criticized him as well with House Speaker Paul Ryan saying:

“There is no question that Russia interfered in our election and continues attempts to undermine democracy here and around the world. That is not just the finding of the American intelligence community but also the House Committee on Intelligence. The president must appreciate that Russia is not our ally. There is no moral equivalence between the United States and Russia, which remains hostile to our most basic values and ideals. The United States must be focused on holding Russia accountable and putting an end to its vile attacks on democracy.”

Although Senate Leader Mitch McConnell was more careful in his wording:

The Russians are not our friends. I’ve said that repeatedly, I say it again today. And I have complete confidence in our intelligence community and the findings that they have announced

More statements can be found here.

One notable exception to the critique is Senator Rand Paul who said in part:

I’m not so sure I would describe it as siding with the Russians.

I would say that President Trump has healthy dose of skepticism towards our intelligence community. And I — I share some of that.

Today, the President tried to walk back these statements, and unfortunately many Republicans have bought into what was said; however, for me, it is too little too late. I believe the President said exactly what he meant and with President Putin playing with a soccer ball and dismissing everything as a kid’s game, I think it’s clear who won.

While some people may follow you blindly, I certainly won’t. You had two opportunities yesterday to clear things up (an interview with Sean Hannity and with Tucker Carlson) and did nothing. It wasn’t until you were on Air Force One that you tweeted saying he had confidence in our intelligence agencies, it wasn’t until the following day (when who knows how many countless advisers had to have smacked some sense into him) that he finally retracted it.

We tend to look at Jimmy Carter’s “General Malaise” speech as one of the worse moments in American history, but I think that this will now top it.

While you can tweet and rally as much as your want, you need to face it Mr. President, your goose is cooked.

Posted in Politics | Tagged , , , | Leave a comment