programming

A 26-post collection

ASP.NET Core, JWT Tokens, and the User.Identity.Name property - A Discovery

Written by Michael Earls
 ASP.NET  programming  .NET Core

I've been working on creating a token-based auth system and I wanted to write about a discovery that I made. I've been following the excellent ASP.NET Core Token Authentication Guide.

I was able to get everything up and running as suggested in the guide, but when I accessed the User.Identity.Name property, it was null. I was hoping to find the Name of the user there, but it wasn't. After some exploration, I was able to determine the solution. You simply add the following code in Startup.cs. I added this to the TokenValidationParameters area as outlined in the Guide.

var tokenValidationParameters = new TokenValidationParameters
{
    // Ensure that User.Identity.Name is set correctly after login
    NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",

    ... Existing code here ...

};

If you want to use a different claim as your User.Identity.Name, then use that claim name instead of the XmlSoap schema above. We're actually not using username, we're using an Id number that identifies the user.

Who am I, really?

Written by Michael Earls
 michael  programming

Due to various circumstances, I recently found myself in the job market again. There was a particular job that emerged that I got very excited about. They cold contacted me through LinkedIn, not knowing that I was even looking for a job.

I had to drive two hours for the first interview, but the job was for working remotely with a little travel. Once in the interview, I noticed that they were asking questions based off of my LinkedIn profile, not off of the resume that I had so carefully crafted to be my own representation of myself.

Honestly, I'm was glad they were using LinkedIn and not my resume because I hate resumes. After working in this industry for over twenty years, the resume that I'm most comfortable with has grown to over six pages long. It's my understanding that it's not supposed to exceed two pages.

So, when I became aware that I was going to have to sell myself again, I created a new resume that was going to be my short version. I even named it "Michael Earls resume 2 page.docx". It's terrible. I still have not found the best way to squeeze over twenty years of knowledge, experience, and wisdom onto just two pages.

During the interview, they asked some good questions about my experience and asked about the projects I had worked on. Remember, this is a job that I really wanted to get as it had to do with industrial automation and that was a field I have been interested in for a very long time.

I finished the interview and felt pretty good about it. Days went by and I never heard anything back. So, I sent an email asking if they had any news. They told me that they were still making a decision.

After a few weeks, I finally just gave up all hope and continued with the other job prospects as normal. Then, out of the blue, I got a call from them asking me to drive up for another interview, this time with the president of the company and other executives. I agreed.

This time, however, I was asked to perform one of those in-depth personality profiles that companies pay for. They were serious and I knew it. I get nervous taking these personality profiles because they make me feel like I'm being analyzed (because I am).

When I got to the interview, it was intense. They were armed with 10 reports about my personality and asked me very pointed questions about who I was and how I would respond to certain scenarios.

During both interviews, I specifically remember telling them that I viewed the work that I do as a creative endeavor. I told them that I see programming as an art form and the act of writing code is like painting a picture.

When asked what my greatest gift was, I said "I make order out of chaos".

Utter bullshit.

I never heard back from them after the second interview, even when I sent an email asking if they had made a decision because I had received another job offer. Personally, I think it was unprofessional to not even tell me that I had not been selected, but each company handles things in their own way.

Going back through the interview, I can remember times when they kept trying to get me back on track. All I had to do was confirm to them that I was the same person from my LinkedIn profile. Nowhere in my career have I ever "painted a picture with code".

I am a software engineer, not an artist. But why did I say those things? What led me to spout off so much untruth?

After some self reflection, I finally realized why I had told them that and why I have had that view of myself since the beginning.

It started in 7th grade.

When I was growing up, I used to draw a lot. I even got in trouble in school for drawing during class to the point where most of my artwork ended up in the trash can (the evil teachers tore it up before placing it there).

I was a huge Iron Maiden fan in Junior High. I loved heavy metal music and I used to draw demons, skeletons, skulls, flames, you get the idea. Iron Maiden's "mascot" is a skeleton with rotting flesh falling from his bones.

I used to emulate that style in my drawings and I drew a lot of it. I also drew post-apocalyptic scenes (much like you see now in The Walking Dead TV show).

One day, there was an announcement that students were encouraged to join the art club. Just show up to the art room after school with some of your drawings to get in. When I knocked on the door, the teacher opened the door, looked at my drawings and said "this is Satanic, you can't be in the art club".

I was deflated. I don't think I've drawn another picture since that day. Yet, somehow, I never stopped thinking of myself as an artist. I originally wanted to go to art school and be a 3-D animator, but that was too expensive and very unrealistic coming from the financial demographic that I come from.

I've somehow been lying to myself all these years that I am an artist, yet nothing that I do is art. It's all engineering and science.

I can imagine that I must come across as a dishonest person when I discuss how I view myself because I have been so clueless for so long.

Now I know who I am, I'm a software engineer and I write code for a living. I don't "paint with code". I solve problems. I am a problem solver and I'm a damn good one.

Pong on the Mojo Revisited

Written by Michael Earls
 FPGA  electronics  programming

In my previous post, I briefly discussed the implementation of a pseudo-pong game on my Mojo FPGA developer board.

I was able to implement the VHDL version that I linked to later in the post and it works much better.

The biggest challenge I had with it was converting the two-button input to a potentiometer input. It turns out all I had to do was convert an array to an integer as input to the paddle's left position.

Here is a link to the article describing the implementation that I used:

FPGA Pong From FPGACenter.com.

The VHDL was a big challenge for me because I had to learn it as I went along. It works just like Verilog, but the syntax is so different.

Also, I modified my User Constraints File to make the RGB an array for compatibility with this particular implementation.

Here are the new custom constraints:

NET "hsync" LOC = P50 | IOSTANDARD = LVTTL;  
NET "vsync" LOC = P51 | IOSTANDARD = LVTTL;  
NET "rgb<2>" LOC = P41 | IOSTANDARD = LVTTL;  
NET "rgb<1>" LOC = P40 | IOSTANDARD = LVTTL;  
NET "rgb<0>" LOC = P35 | IOSTANDARD = LVTTL;

Here is the code containing my changes (in the vga_control and img_gen modules):

vga_control:

library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;  
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity vga_control is  
     Port ( clk : in STD_LOGIC;
                start : in STD_LOGIC;
                reset : in STD_LOGIC;
                paddle : IN STD_LOGIC_VECTOR(9 downto 0);
                rgb : out STD_LOGIC_VECTOR (2 downto 0);
                h_s : out STD_LOGIC;
                v_s : out STD_LOGIC);
end vga_control;

architecture Behavioral of vga_control is

COMPONENT img_gen  
       PORT( clk : IN std_logic;
                     x_control : IN std_logic_vector(9 downto 0);
                     paddle : IN std_logic_vector(9 downto 0);
                     y_control : IN std_logic_vector(9 downto 0);
                     video_on : IN std_logic; 
                     rgb : OUT std_logic_vector(2 downto 0) );
END COMPONENT;

COMPONENT sync_mod  
       PORT( clk : IN std_logic;
                     reset : IN std_logic;
                     start : IN std_logic; 
                     y_control : OUT std_logic_vector(9 downto 0);
                     x_control : OUT std_logic_vector(9 downto 0);
                     h_s : OUT std_logic;
                     v_s : OUT std_logic;
                     video_on : OUT std_logic );
END COMPONENT;

signal x,y:std_logic_vector(9 downto 0);  
signal video:std_logic;

begin  
          U1: img_gen PORT MAP( clk =>clk , x_control => x, paddle => paddle , 
                                                         y_control => y, video_on =>video , rgb => rgb );

           U2: sync_mod PORT MAP( clk => clk, reset => reset, start => start, y_control => y, x_control =>x ,
                                                             h_s => h_s , v_s => v_s, video_on =>video );
end Behavioral;

My changes are on lines 9, 20, and 41. This sends the output from the potentiometer hooked up to the ADC on the Mojo to the img_gen module where it's converted to position data for the paddle control.

Here's the modified img_gen code:

library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;  
use IEEE.STD_LOGIC_ARITH.ALL;  
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity img_gen is  
     Port ( clk : in STD_LOGIC;
                x_control : in STD_LOGIC_VECTOR(9 downto 0);
                paddle : in STD_LOGIC_VECTOR(9 downto 0);
                y_control : in STD_LOGIC_VECTOR(9 downto 0);
                video_on : in STD_LOGIC;
                rgb : out STD_LOGIC_VECTOR(2 downto 0));
end img_gen;

architecture Behavioral of img_gen is

--wall
constant wall_l:integer :=10;--the distance between wall and left side of screen  
constant wall_t:integer :=10;--the distance between wall and top side of screen  
constant wall_k:integer :=10;--wall thickness  
signal wall_on:std_logic;  
signal rgb_wall:std_logic_vector(2 downto 0); 

--bar
signal bar_l, bar_l_next: integer:=100;  
constant bar_t:integer :=420;--the distance between bar and top side of screen  
constant bar_k:integer :=10;--bar thickness  
constant bar_w:integer:=120;--bar width  
constant bar_v:integer:=10;--velocity of the bar  
signal bar_on:std_logic;  
signal rgb_bar:std_logic_vector(2 downto 0); 

--ball
signal ball_l,ball_l_next:integer :=100;--the distance between ball and left side of screen  
signal ball_t,ball_t_next:integer :=100; --the distance between ball and top side of screen  
constant ball_w:integer :=20;--ball Height  
constant ball_u:integer :=20;--ball width  
constant x_v,y_v:integer:=3;-- horizontal and vertical speeds of the ball  
signal ball_on:std_logic;  
signal rgb_ball:std_logic_vector(2 downto 0); 

--refreshing(1/60)
signal refresh_reg,refresh_next:integer;  
constant refresh_constant:integer:=830000;  
signal refresh_tick:std_logic;

--ball animation
signal xv_reg,xv_next:integer:=3;--variable of the horizontal speed  
signal yv_reg,yv_next:integer:=3;--variable of the vertical speed

--x,y pixel cursor
signal x,y:integer range 0 to 650;

--mux
signal vdbt:std_logic_vector(3 downto 0);

--buffer
signal rgb_reg,rgb_next:std_logic_vector(2 downto 0);

begin

--x,y pixel cursor
x <= conv_integer(x_control);  
y <= conv_integer(y_control );

--refreshing
process(clk)  
begin  
     if clk'event and clk='1' then
          refresh_reg<=refresh_next; 
     end if;
end process;  
refresh_next <= 0 when refresh_reg= refresh_constant else  
refresh_reg+1;  
refresh_tick <= '1' when refresh_reg = 0 else  
                           '0';
--register part
process(clk)  
begin  
     if clk'event and clk='1' then
         ball_l <= ball_l_next;
         ball_t <= ball_t_next;
         xv_reg <= xv_next;
         yv_reg <= yv_next;
         bar_l <= bar_l_next;
      end if;
end process;

--bar animation
process(refresh_tick,paddle)  
begin

    if refresh_tick= '1' then
       bar_l_next <= conv_integer(paddle);
    end if;
end process;

--ball animation
process(refresh_tick,ball_l,ball_t,xv_reg,yv_reg)  
begin  
     ball_l_next <=ball_l;
     ball_t_next <=ball_t;
     xv_next <= xv_reg;
     yv_next <= yv_reg;
     if refresh_tick = '1' then
        if ball_t > 400 and ball_l > (bar_l -ball_u) and ball_l < (bar_l +120) then --the ball hits the bar
           yv_next <= -y_v ;
       elsif ball_t < 35 then--The ball hits the wall
           yv_next <= y_v;
       end if;
       if ball_l < 10 then --The ball hits the left side of the screen
          xv_next <= x_v;
       elsif ball_l> 600 then 
          xv_next <= -x_v ; --The ball hits the right side of the screen
       end if; 
       ball_l_next <= ball_l + xv_reg;
       ball_t_next <= ball_t + yv_reg; 
    end if;
end process;

--wall object
wall_on <= '1' when x > wall_l and x < (640-wall_l) and y> wall_t and y < (wall_t+ wall_k) else  
                      '0'; 
rgb_wall <= "000";--Black  
--bar object
bar_on <= '1' when x > bar_l and x < (bar_l+bar_w) and y> bar_t and y < (bar_t+ bar_k) else  
                    '0'; 
rgb_bar <= "001";--blue

--ball object
ball_on <= '1' when x > ball_l and x < (ball_l+ball_u) and y> ball_t and y < (ball_t+ ball_w) else  
                     '0'; 
rgb_ball <= "010"; --Green

--buffer
process(clk)  
begin  
     if clk'event and clk = '1' then
         rgb_reg <= rgb_next;
     end if;
end process;

--mux
vdbt<=video_on & wall_on & bar_on &ball_on;  
with vdbt select  
     rgb_next <= "100" when "1000",--Background of the screen is red 
     rgb_wall when "1100",
     rgb_wall when "1101",
     rgb_bar when "1010",
     rgb_bar when "1011",
     rgb_ball when "1001",
      "000" when others;
--output
rgb <= rgb_reg;

end Behavioral;

My changes are on lines 10 and 95 to make the potentiometer control the paddle.

Creating PONG on the Mojo FPGA

Written by Michael Earls
 FPGA  electronics  programming

I recently found an old VGA monitor on the side of the road and it inspired me to see if I could get my Mojo FPGA board to output a VGA signal. I took the monitor apart and wired its VGA cable directly to my Mojo.

I read up on the VGA specification and learned that getting it to work was as easy as adding resistors to the Red, Green, and Blue outputs.

VGA Connector

I decided to try my hand at implementing the PONG game that is outlined on fpga4fun.com.

There were some differences between that FPGA that they were using and my Mojo board, so I had to go through some trial-and-error.

For instance, the Verilog code that they have on the site depends on a 25MHz clock and my Mojo uses a 50MHz clock. I tried various ways of dividing the clock without success.

I finally found a great example using a 50MHz clock, but it wasn't quite right because it used 8-bits to encode the RGB values, 3 bits for red and green, and 2 bits for blue. I couldn't get this to work, so I found the code that it was based on and found 1 bit per color implementation. I was finally able to get a signal.

The rest of the time was spent implementing the Pong code from the original article. However, the article used a mouse input. I wanted to use a regular potentiometer (dial) to make it more like the "good old days". So, I wired up a pot to the Mojo and altered the Verilog to use it.

Honestly, my code turned out to be spaghetti code because I haven't quite learned how to modularize Verilog to my satisfaction.

I was able to get the paddle working and responding to movement of the potentiometer, but for some reason, the code for the ball just didn't work in my implementation. I'm guessing it has to do with the timing. I still haven't been able to get the ball working, but I was pretty happy that the paddle works.

The Mojo wired to the VGA cable and the paddle The Mojo wired to the VGA cable and the paddle "controller"

The pong paddle The paddle "controller" - a simple 10k potentiometer

Here is the Verilog definition for the Pong module:

`timescale 1ns / 1ps  
module pong(clk, red, green, blue, hsync, vsync, pot_sample);

// Input clk, 50 MHz Oscillator
input clk;  
input [9:0]pot_sample;

// VGA outputs
output red;  
output green;  
output blue;  
output hsync;  
output vsync;     

reg [9:0] hcount;     // VGA horizontal counter  
reg [9:0] vcount;     // VGA vertical counter  
reg [2:0] data;          // RGB data

wire hcount_ov;  
wire vcount_ov;  
wire inDisplayArea;  
wire hsync;  
wire vsync;  
reg  vga_clk;

// VGA mode parameters
parameter hsync_end   = 10'd95,  
   hdat_begin  = 10'd143,
   hdat_end  = 10'd783,
   hpixel_end  = 10'd799,
   vsync_end  = 10'd1,
   vdat_begin  = 10'd34,
   vdat_end  = 10'd514,
   vline_end  = 10'd524;


always @(posedge clk)  
begin  
 vga_clk = ~vga_clk;
end

always @(posedge vga_clk)  
begin  
 if (hcount_ov)
  hcount <= 10'd0;
 else
  hcount <= hcount + 10'd1;
end

assign hcount_ov = (hcount == hpixel_end);

always @(posedge vga_clk)  
begin  
 if (hcount_ov)
 begin
  if (vcount_ov)
   vcount <= 10'd0;
  else
   vcount <= vcount + 10'd1;
 end
end  
assign  vcount_ov = (vcount == vline_end);

////////////////////////////////////////////////////////////////
// Pong
////////////////////////////////////////////////////////////////
// Handle paddle position
reg [9:0] PaddlePosition;

always @(posedge vga_clk) begin

        PaddlePosition <= hdat_begin + pot_sample;

    if(0)
    begin
      if(0)
      begin
         if(~&PaddlePosition)        // make sure the value doesn't overflow
            PaddlePosition <= PaddlePosition + 1;
      end 
      else
      begin
         if(|PaddlePosition)        // make sure the value doesn't underflow
            PaddlePosition <= PaddlePosition - 1;
      end
    end
end

wire paddle = (hcount >= PaddlePosition + 8) && (hcount <= PaddlePosition+120) && ((vcount <= vdat_end - 15) && (vcount > vdat_end - 25));

// Draw a border around the screen
wire border = ((hcount >=  hdat_begin) && (hcount <  hdat_begin + 10)) || ((hcount >  hdat_end - 10) && (hcount <=  hdat_end))  
    || ((vcount >= vdat_begin) && (vcount < vdat_begin + 10)) || ((vcount > vdat_end - 10) && (vcount <= vdat_end));

//////////////////////////////////////////////////////////////////
reg [9:0] ballX;  
reg [9:0] ballY;  
reg ball_inX, ball_inY;

always @(posedge vga_clk)  
if(ball_inX==0) ball_inX <= ((hcount>ballX) && (hcount<=ballX+16)) & ball_inY; else ball_inX <= 0;//!(hcount==ballX+16);

always @(posedge vga_clk)  
if(ball_inY==0) ball_inY <= ((vcount>ballY) && (vcount<=ballY+16)); else ball_inY <= 0;//!(vcount==ballY+16);

wire ball = ball_inX & ball_inY;

/////////////////////////////////////////////////////////////////
wire BouncingObject = border | paddle; // active if the border or paddle is redrawing itself

reg ResetCollision;  
always @(posedge vga_clk) ResetCollision <= (vcount==0) & (hcount==0);  // active only once for every video frame

reg CollisionX1, CollisionX2, CollisionY1, CollisionY2;  
always @(posedge vga_clk) if(ResetCollision) CollisionX1<=0; else if(BouncingObject & (hcount==ballX   ) & (vcount==ballY+ 8)) CollisionX1<=1;  
always @(posedge vga_clk) if(ResetCollision) CollisionX2<=0; else if(BouncingObject & (hcount==ballX+16) & (vcount==ballY+ 8)) CollisionX2<=1;  
always @(posedge vga_clk) if(ResetCollision) CollisionY1<=0; else if(BouncingObject & (hcount==ballX+ 8) & (vcount==ballY   )) CollisionY1<=1;  
always @(posedge vga_clk) if(ResetCollision) CollisionY2<=0; else if(BouncingObject & (hcount==ballX+ 8) & (vcount==ballY+16)) CollisionY2<=1;

/////////////////////////////////////////////////////////////////
wire UpdateBallPosition = ResetCollision;  // update the ball position at the same time that we reset the collision detectors

reg ball_dirX, ball_dirY;  
always @(posedge vga_clk)  
if(UpdateBallPosition)  
begin  
    if(~(CollisionX1 & CollisionX2))        // if collision on both X-sides, don't move in the X direction
    begin
        ballX <= ballX + (ball_dirX ? -1 : 1);
        if(CollisionX2) ball_dirX <= 1; else if(CollisionX1) ball_dirX <= 0;
    end

    if(~(CollisionY1 & CollisionY2))        // if collision on both Y-sides, don't move in the Y direction
    begin
        ballY <= ballY + (ball_dirY ? -1 : 1);
        if(CollisionY2) ball_dirY <= 1; else if(CollisionY1) ball_dirY <= 0;
    end
end 

/////////////////////////////////////////////////////////////////

// display area calculation
assign inDisplayArea = ((hcount >= hdat_begin) && (hcount < hdat_end))  
     && ((vcount >= vdat_begin) && (vcount < vdat_end));

assign hsync = (hcount > hsync_end);  
assign vsync = (vcount > vsync_end);

reg vga_R, vga_G, vga_B;

always @(posedge vga_clk)  
begin  
  vga_R <= BouncingObject | ball;
  vga_G <= BouncingObject | ball;
  vga_B <= BouncingObject | ball;
end

assign red = (inDisplayArea) ?  vga_R : 0;  
assign green = (inDisplayArea) ?  vga_G : 0;  
assign blue = (inDisplayArea) ?  vga_B : 0;      


// generate "image"
always @(posedge vga_clk)  
begin  
  data <= (vcount[2:0] ^ hcount[2:0]); 
end

endmodule

Line #6 is the direct input of the potentiometer from the Mojo's on-board Analog to Digital Converter (ADC). Here is the top file showing how it's all wired together:

module mojo_top(  
    // 50MHz clock input
     input clk,
    // Input from reset button (active low)
    input rst_n,
    // cclk input from AVR, high when AVR is ready
    input cclk,
    // Outputs to the 8 onboard LEDs
    output[7:0]led,
    // AVR SPI connections
    output spi_miso,
    input spi_ss,
    input spi_mosi,
    input spi_sck,
    // AVR ADC channel select
    output [3:0] spi_channel,
    // Serial connections
    input avr_tx, // AVR Tx => FPGA Rx
    output avr_rx, // AVR Rx => FPGA Tx
    input avr_rx_busy, // AVR Rx buffer full
     output  red,
    output  green,
    output  blue,
    output hsync, vsync
    );

wire rst = ~rst_n; // make reset active high

// these signals should be high-z when not used
assign spi_miso = 1'bz;  
assign avr_rx = 1'bz;  
assign spi_channel = 4'bzzzz;

assign led = 8'b0;

wire [3:0] channel;  
wire new_sample;  
wire [9:0] sample;  
wire [3:0] sample_channel;  
wire [9:0] pot_sample;

avr_interface avr_interface (  
 .clk(clk),
 .rst(rst),
 .cclk(cclk),
 .spi_miso(spi_miso),
 .spi_mosi(spi_mosi),
 .spi_sck(spi_sck),
 .spi_ss(spi_ss),
 .spi_channel(spi_channel),
 .tx(avr_rx),
 .rx(avr_tx),
 .channel(channel),
 .new_sample(new_sample),
 .sample(sample),
 .sample_channel(sample_channel),
 .tx_data(8'h00),
 .new_tx_data(1'b0),
 .tx_busy(),
 .tx_block(avr_rx_busy),
 .rx_data(),
 .new_rx_data()
);

 input_capture input_capture (
 .clk(clk),
 .rst(rst),
 .channel(channel),
 .new_sample(new_sample),
 .sample(sample),
 .sample_channel(sample_channel),
 .sample_out(pot_sample)
);

pong pongBoard(  
    .clk(clk), 
    .red(red),
    .green(green),
    .blue(blue),
    .hsync(hsync),
    .vsync(vsync),
    .pot_sample(pot_sample)
);

endmodule

And, finally, here are the custom user constraints that I used to wire the output pins up to the VGA connector:

NET "hsync" LOC = P50 | IOSTANDARD = LVTTL;  
NET "vsync" LOC = P51 | IOSTANDARD = LVTTL;  
NET "red" LOC = P41 | IOSTANDARD = LVTTL;  
NET "green" LOC = P40 | IOSTANDARD = LVTTL;  
NET "blue" LOC = P35 | IOSTANDARD = LVTTL;

I'd really like to get the ball working with this. My scoring will be different than traditional Pong as I am not yet ready to tackle the "AI" of the computer player. I'd like the player to score 1 point each time the ball hits the paddle and lose a point each time the ball hits the bottom wall. If the ball hits the bottom wall while the score is 0, then the game is over. I'll have to add in a reset button, but that shouldn't be much trouble.

I just found another implementation of Pong in VHDL that I may try later. It divides the 50MHz clock into a 25MHz clock using a mod 2 counter. I discuss my implementation of that code in another post.

I haven't written any VHDL, yet, so I'm still trying to wrap my head around it. It was hard enough switching from Mojo's Lucid language to Verilog as Lucid made things a bit easier. However, I felt that since there were a lot more people out there using Verilog that I would be better off learning that. Now I'm learning that there are even more people using VHDL.

Lucid, Verilog, and VHDL are a far cry from C#, C, and JavaScript; three languages I'm very familiar with. This has been a very beneficial lesson in parallel "programming".

Moon Phase Calculator for the Pebble Watch (C Source)

Written by Michael Earls
 programming  development

A few years ago, I bought a Pebble smartwatch. Mostly I bought it because it was cheap, but I also wanted to write my own apps for it. I wrote a few apps.

Recently, Pebble was bought by FitBit and ceased production of the Pebble smartwatch. However, they are making great progress to ensuring that the watch continues to be viable into the future.

Anyway, as part of the transition, I wanted to release my source code for my moon phase app. What sets this moon phase calculator apart from my first implementation is the ability for it to run when not connected to the phone. I implemented it as a C app.

The moon phase calculation itself was originally written in JavaScript and I had to convert it to C. Sadly, I can't remember where I got the source, so I can't give attribution.

The code is available on my GitHub Page:

pebble-moon-phase on GitHub

Here is the actual calculation for anyone searching for a moon phase calculator in C:

#include "math.h"

#define        PI  3.1415926535897932384626433832795
#define        RAD (PI/180.0)
#define         SMALL_FLOAT    (1e-12)

static double Julian(int year,int month,double day)  
{
    /*
      Returns the number of julian days for the specified day.
      */

    int a,b=0,c,e;
    if (month < 3) {
    year--;
    month += 12;
    }
    if (year > 1582 || (year  1582 && month>10) ||
    (year  1582 && month==10 && day > 15)) {
    a=year/100;
    b=2-a+a/4;
    }
    c = 365.25*year;
    e = 30.6001*(month+1);
    return b+c+e+day+1720994.5;
}

static double sun_position(double j)  
{
    double n,x,e,l,dl,v;
    //double m2;
    int i;

    n=360/365.2422*j;
    i=n/360;
    n=n-i*360.0;
    x=n-3.762863;
    if (x<0) x += 360;
    x *= RAD;
    e=x;
    do {
    dl=e-.016718*sin(e)-x;
    e=e-dl/(1-.016718*cos(e));
    } while (fabs(dl)>=SMALL_FLOAT);
    v=360/PI*atan(1.01686011182*tan(e/2));
    l=v+282.596403;
    i=l/360;
    l=l-i*360.0;
    return l;
}

static double moon_position(double j, double ls)  
{

    double ms,l,mm,n,ev,sms,ae,ec;//,z,x;//,lm,bm,ec;
    //double d;
    //double ds, as, dm;
    int i;

    /* ls = sun_position(j) */
    ms = 0.985647332099*j - 3.762863;
    if (ms < 0) ms += 360.0;
    l = 13.176396*j + 64.975464;
    i = l/360;
    l = l - i*360.0;
    if (l < 0) l += 360.0;
    mm = l-0.1114041*j-349.383063;
    i = mm/360;
    mm -= i*360.0;
    n = 151.950429 - 0.0529539*j;
    i = n/360;
    n -= i*360.0;
    ev = 1.2739*sin((2*(l-ls)-mm)*RAD);
    sms = sin(ms*RAD);
    ae = 0.1858*sms;
    mm += ev-ae- 0.37*sms;
    ec = 6.2886*sin(mm*RAD);
    l += ev+ec-ae+ 0.214*sin(2*mm*RAD);
    l= 0.6583*sin(2*(l-ls)*RAD)+l;
    return l;
}

static double moon_phase2(int year,int month,int day, double hour, int* ip)  
{
    /*
      Calculates more accurately than Moon_phase , the phase of the moon at
      the given epoch.
      returns the moon phase as a real number (0-1)
      */

    double j= Julian(year,month,(double)day+hour/24.0)-2444238.5;
    double ls = sun_position(j);
    double lm = moon_position(j, ls);

    double t = lm - ls;
    if (t < 0) t += 360;
    *ip = (int)((t + 22.5)/45) & 0x7;
    return (1.0 - cos((lm - ls)*RAD))/2;
}

Solving the Stable Marriage problem on an FPGA (Part 2)

Written by Michael Earls
 Mathematics  FPGA  electronics  programming

In part 1, I introduced the Stable Marriage problem and proposed implementing it on an FPGA.

In this post, I will define the approach I am taking to define the preferences in binary form.

Series entries:

Note: Blog title image used without permission (pending) from numberphile.com

Since we're only dealing with eight people (four women and four men), I decided to use a 2-bit number to define the Id number of the person within their gender.

With a 2-bit number, that gives us the following Id's to work with (per gender):

  • Person #1 - 00
  • Person #2 - 01
  • Person #3 - 10
  • Person #4 - 11

To define the preferences for each person, we can take advantage of the fact that we're only using 2-bits per id and only have four preferences. That means we can use a single byte to define the preferences, with the most significant 2 bits being the first choice.

Here is a table to illustrate some sample preferences:

Proposal Table (Decimal)

Females
Id 1st 2nd 3rd 4th
1 2 1 4 3
2 2 4 3 1
3 2 1 4 3
4 4 3 2 1
Males
Id 1st 2nd 3rd 4th
1 4 3 2 1
2 3 1 2 4
3 4 3 1 2
4 2 4 3 1

So, let's take a look at our proposal cycles using this table:

First cycle

Here are the proposals:

  • Woman 1: Man 2
  • Woman 2: Man 2
  • Woman 3: Man 2
  • Woman 4: Man 4

So, Man 2 now has 3 proposals (Woman 1, Woman 2, and Woman 3). If we look at his preferences (3, 1, 2, 4), we see that he prefers Woman 3 over Women 1 and 2, so he declines them and accepts a tentative proposal from Woman 3 (since this is the first match and they both are top of each other's list, they won't be matched with another person, but that is a fact that we can deduce as humans that we can't expect the machine to know).

Woman 4 is tentatively engaged to Man 4.

Women 1 and 2 are left out because they were declined, so they'll propose to their second choice on the second cycle.

At the end of the cycle we have the following state for the Women:

  • Woman 1: unmatched
  • Woman 2: unmatched
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: tentatively engaged to Man 4

Second cycle

Here are the choices

  • Woman 1: Man 1
  • Woman 2: Man 4
  • Woman 3: N/A (tentatively engaged)
  • Woman 4: N/A (tentatively engaged)

Woman 1 proposes to her 2nd choice, Man 1. Man 1 has not been proposed to yet, so he'll accept.

Woman 2 proposes to Man 4, but he is tentatively engaged to Woman 4. However, since Woman 2 is his first choice, he declines Woman 4 and "trades up" to accept the new proposal from Woman 2.

This leaves Woman 4 alone to propose in the third cycle.

At the end of the cycle we have the following state for the Women:

  • Woman 1: tentatively engaged to Man 1
  • Woman 2: tentatively engaged to Man 4
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: unmatched

Third cycle

Here are the choices

  • Woman 1: N/A (tentatively engaged)
  • Woman 2: N/A (tentatively engaged)
  • Woman 3: N/A (tentatively engaged)
  • Woman 4: Man 2

So, Woman 4 proposes to Man 2, but he prefers his current fiance, so he declines her.

At the end of the cycle we have the following state for the Women:

  • Woman 1: tentatively engaged to Man 1
  • Woman 2: tentatively engaged to Man 4
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: (still) unmatched

Fourth cycle

Here are the choices

  • Woman 1: N/A (tentatively engaged)
  • Woman 2: N/A (tentatively engaged)
  • Woman 3: N/A (tentatively engaged)
  • Woman 4: Man 1

Woman 4 proposes to Man 1, but he is tentatively engaged to Woman 1. However, Woman 4 is is top choice, so he declines Woman 1's proposal and "trades up" to accept Woman 4's proposal.

This leaves Woman 1 alone again, forcing her to propose in the next cycle.

At the end of the cycle we have the following state for the Women:

  • Woman 1: unmatched
  • Woman 2: tentatively engaged to Man 4
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: tentatively engaged to Man 1

Fifth cycle

Here are the choices

  • Woman 1: Man 4
  • Woman 2: N/A (tentatively engaged)
  • Woman 3: N/A (tentatively engaged)
  • Woman 4: N/A (tentatively engaged)

Woman 1 proposes to Man 4, but he is already engaged to his top preference, so he declines her proposal. This leaves her alone again for the next cycle.

At the end of the cycle we have the following state for the Women:

  • Woman 1: (still) unmatched
  • Woman 2: tentatively engaged to Man 4
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: tentatively engaged to Man 1

Sixth cycle

Here are the choices

  • Woman 1: Man 3
  • Woman 2: N/A (tentatively engaged)
  • Woman 3: N/A (tentatively engaged)
  • Woman 4: N/A (tentatively engaged)

Woman 1 proposes to Man 3, who is currently free, so he accepts her proposal.

At the end of the cycle we have the following state for the Women:

  • Woman 1: tentatively engaged to Man 3
  • Woman 2: tentatively engaged to Man 4
  • Woman 3: tentatively engaged to Man 2
  • Woman 4: tentatively engaged to Man 1

We now have no more unmatched Women, so our cycles are complete and we have stable marriages.

Here are the final results:

  • Woman 1: engaged to Man 3
  • Woman 2: engaged to Man 4
  • Woman 3: engaged to Man 2
  • Woman 4: engaged to Man 1

Here is the proposal table in binary (with 2-bit Id's)

Females
Id 1st 2nd 3rd 4th
00 01 00 11 10
01 01 11 10 00
10 01 00 11 10
11 11 10 01 00
Males
Id 1st 2nd 3rd 4th
00 11 10 01 00
01 10 00 01 11
10 11 10 00 01
11 01 11 10 00

So to represent the preferences of the Women, we simply create a byte containing their preferences.

Here they are for each woman:

  • Woman 1 (00) - 01001110
  • Woman 2 (01) - 01111000
  • Woman 3 (10) - 01001110
  • Woman 4 (11) - 11100100

Note: It's important to notice that I'm referring to them in 1-based decimal (Woman 1, 2, 3, 4), but 0-based binary (Woman 00, Woman 01, Woman 10, Woman 11).

So, to represent these preferences we simply need four sets of 4-bit numbers representing the matching for the women. So, our final results would look like this in binary:

0010 0111 1001 1100

I'm not considering how to scale this out, yet, so I'm making some assumptions on the feasibility of using 2-bit id's rather than full bytes. In the end, a full byte will give us more people, but I wanted to keep this simple. I hope by starting this way I don't adversely effect the overall solution.

Now that I've established the preferences and a way to represent them in binary, I need to figure out the best way to store them and run the cycles on the FPGA.

Next up, defining our finite state machines (FSMs).

Solving the Stable Marriage problem on an FPGA (Part 1)

Written by Michael Earls
 Mathematics  FPGA  programming

At my last client, there was an issue that came up that required matching between two groups. It had to be a fair matching based on preferences of both sides. I first started by writing my own algorithm, but I quickly realized that someone has to have come up with something to do this already. I was right. Not only had someone(s) figured the problem out, they received a Nobel Prize for their work (good thing I didn't try to tackle it on my own).

Note: Blog title image used without permission (pending) from numberphile.com

Series entries:

The algorithm is named after the two mathematicians who discovered it: the Gale–Shapley algorithm, or commonly called the Stable Marriage Problem (or stable matching problem - SMP). I'll let you read about it on Wikipedia as I don't just want to repeat what's already there. Basically, it's also used in the National Resident Matching Program to help match medical students to residency programs, so it has real-world applications beyond the classroom.

Here is a great video describing the algorithm in layman's terms:

And for some deeper math, here is the follow-up to that video:

I became obsessed with this algorithm while working with the client because they had some unique ways of determining preferences beyond just saying "I like guy 2". There had to be more to it. "I like guy 2 because...".

My work obsession happened to coincide with my home obsession of learning how to utilize and develop on FPGAs. Again, I'll let you read the details, but the best way to describe an FPGA (compared to a microcontroller like the Arduino or Raspberry Pi) is as follows (I read this somewhere on the Internet and it stuck in my head):

  • You tell a microcontroller what to do.
  • You tell an FPGA what to be

There's a nuance there that has enormous implications on the differences between the two. FPGAs are much faster than microcontrollers because all of the logic runs in parallel, whereas a microcontroller has to run a program in a tight loop and constantly check and update the status of its IO pins. Every time you add a new task to a microcontroller's program, you slow it down.

Here is a video from Microsoft's Channel 9 discussing research they are doing on using FPGAs in the data center (Bing specifically) to increase performance and save energy:

Since the SMB algorithm can be so processor-intensive, I thought it might be cool to implement it on FPGA hardware to see if I can pull it off.

To keep things simpler for me, my initial approach is only going to deal with 8 total people: 4 women, and 4 suitors. I will take the "women propose" approach as discussed in the video above.

Next: Establishing the preferences...

How I accidentally learned something unexpected from a simple binary counter

Written by Michael Earls
 electronics  Mathematics  programming  binary

In my previous post, I talked about how I implemented a binary counter with my Mojo FPGA board.

I am working on a follow-up post on implementing a reverse binary counter with a switch that lets you change between the incrementing ( UP ) counter and the decrementing ( DOWN ) counter.

I accidentally discovered a property of 8 bit numbers. It's referred to as the "Ones' complement".

When you add a number n between 0 and 255 to an 8-bit binary representation of 0, the same number n subtracted from 255 will be the binary inverse (bit complement) of the first number.

To demonstrate, let's say we start with an 8-bit number at 0:

00000000

Now, we add 2:

00000010

OK, let's look what happens when we have 255:

11111111

Now, let's subtract 2:

11111101

So, comparing them, one above the other, we can see that they are inverse:

00000010  
11111101

This is true for all numbers between 0 and 255 (the only assertion I can personally make through observation).

So, in my original implementation of the reverse binary counter, I was using two counters to keep up with the numbers; one that started at 0 and counted up, and one that started at 255 and counted down.

As I switched between the two to test my design, I noticed the inversion almost immediately. This might be a neat trick when you want to flash LED's, too.

I think a more efficient implementation to replace the DOWN counter is to apply a simple inverter to each bit.

ones' complement inverter for 8-bit number ones' complement inverter for 8-bit number

This is what happens when you learn in reverse. Rather than simply being taught this in a ten minute aside from a lecture, I had to accidentally discover it. I'm learning electronics engineering from a hobbyists perspective, so I'm avoiding the theory and the complex math that makes it actual engineering. I'm sure I'll learn a lot more in the coming years.

This hobby never stops giving...