Skip to contentSkip to author details

C#

A 13-post collection

Entity Framework Composable Queries using LinqKit

Written by Jeff Tyler
 EntityFramework  C#  LinqKit  SQL  Queries  Composable

One of the biggest drawbacks to SQL is the inability to reuse pieces of a query. Technically you can create views but then you wind up joining views to views consuming views and performance goes down the drain.

What if there was away to write a query once and then reuse that query anywhere that you needed that data and have the query injected into each of the queries. Changing one query suddenly changes all of them. Which maintains the DRY principal and once you have a query figured out nobody else has to rewrite the same thing.

With Entity Framework this seems like a simple solution. You write a query in a method and call the method inside of Entity Framework. Seems to make logical since, but when you run it you get an error informing you that there is an unknown method in the query. So now what...

Enter LinqKit https://github.com/scottksmith95/LINQKit...
LinqKit is a project that intercepts an expression and modifies it from something that entity framework will throw an error on to something that it can use.
it allows you to compose queries and reuse them so that you can apply the DRY prinicpal to your queries

For this example we are going to have a parent
each parent has a collection of children
each child has a collection of schools that are the schools that the child has attened

public class Parent  
{
   public int Id{get;set;}
   public string name{get;set;}
   public virtual ICollection<Child> Children {get;set;}
}
public class Child  
{
    public int Id{get;set;}
    public int ParentId {get;set;}
    public int Age{get;set;}
    [ForeignKey(nameof(ParentId))]
    public Parent Parent{get;set;}

    // many to many
    public ICollection<School> School{get;set;}
}

public School  
{
    public Id{get;set;}
    public ICollection<Child> Children{get;set;}
}

So we have a parent with a list of children
Now we want to get the children that are still less then 18
The query would like like

var minors = Db.Parents.Select(parent=> new {parent = parent, child = parent.Children.Where(child=> child.Age < 18});  

For each of the Parents we project to an anonymous object that holds the parent and a collection of their children that are less than 18.

Here is the same query with LinqKit

public static class ParentCompositions  
{
    public static Expression<Func<Parent,IQueryable<Child>>> Minors = 
    parent=>parent.Children.Where(child=> child.< 18);
}

Db.Parents.AsExpandable().Select(parent=>new {parent = parent, child = ParentCompositions.Minors.Invoke(parent)}  

As you can see we the compositon class now has a field that holds an expression representation of the same query we used earlier. The query calls AsExpandable on on the IQueryable Parents. AsExpandable is the method the LinqKit uses to intercept the query. Then in the select method we call Invoke which lets LinqKit know that it needs to intercept it. The SQL generated between the two examples will be exactly the same.

The cool thing about it is now anytime we need minor children for a parent, all we have to do is call the composition.

Now most of the time we don't get away with querying only one or two tables. So Lets get all of the parents and there children that are in high school and still a minor

public class Compositions  
{
     public class ChildSchoolQueryResult
     {
       public Child Child {get;set;}
       public School School {get;set;}
     }

     public class ParentsWithChildrenInSchoolQueryResult
     {
        public Parent Parent {get;set;}
        IQueryable<ChildSchoolQueryResult> ChildrenSchools{get;set}
     }
     public static Expression<Func<Child, ChildSchool>> LastSchoolAttended = 
        child => new ChildSchool { 
              Child = child,
              School = child.Schools.FirstOrDefault(school => school.Id == 
                                             child.Schools.Max(s2=>s2.Id)
                 };

     public static Expression<Func<Parent, ParentsWithChildrenInSchoolQueryResult>> 
     SchoolDependants= p=> 
            new ParentsWithChildrenInSchoolQueryResult{
               parent = p,
               ChildrenInSchool = 
               LastSchoolAttended.Invoke(ParentCompositions.Minors.Invoke(p).AsExpandable)
};

var HighSchoolDependants = Db.Parents.Select(parent=>  
    new { 
    Parent = parent, 
    children = p.children.where(c=> c.Age <= 18)
        .Select(child=> 
             new {
                     Child = child,
                     School = child.Schools.FirstOfDefault(
                       school => school.id == child.schools.Max(school2=>school2.Id)})
                }
       });
    }
}).Where(p=>p.Children.Any(p=>p.School.Name == "High School");
// LinqKit
var HighSchoolDependants = Db.Parents.Select(parent => Compositions.SchoolDependants.Invoke(parent))  
.where(p=>p.ChildrenSchools.Any(s=>School.Name == "High School"));
}

This is a good example of the two styles and their pros and cons.
Pros
Change the Composition changes the result everywhere
Complicated queries only get wrote once

Cons
Thought must be taken to create compositions correctly

Without LinqKit
Pros
No extra library
All logic is in one place

Cons
Logic has to be duplicated
Complicated Queries must be recopied


Driving the Max 7219 7-Segment Display Module from ASP.NET Core on the Raspberry Pi

Written by Michael Earls
 programming  electronics  raspberry pi  C#  .NET Core

In a previous blog post, I discussed how to create a dotnet core 2.0 WebApi application to run on the Raspberry Pi and trigger an LED. This post will build upon that by outlining the steps I took to connect a Max 7219 7-Segment Display Module to the Pi and extend my WebApi to display numbers on the display.

I recently purchased a Max 7219 7-Segment Display Module on eBay. It came in the mail today and I got right to work interfacing it with my Raspberry Pi. I used the excellent instructions found in this post on Plingboot:

Driving the Max7219 with the Raspberry Pi.

I had to convert the C++ code to C# to get it to work with dotnet core, but that didn't take too long. I also added a hex decoder and the ability to use multiple digits.

I hooked up my Pi using the following pin configuration:

  • Pin 11 (Gpio 17) - Data (DIN)
  • Pin 15 (Gpio 22) - Clock (CLK)
  • Pin 16 (Gpio 23) - Load (CS)
  • Pin 1 (3.3v) - 220 Ohm resistor, then to VCC
  • Pin 6 (GND) - GND

I used the same Cake code and foundation WebApi code and added a new Controller for the Max7219. Here is the code:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using Microsoft.AspNetCore.Mvc;  
using Unosquare.RaspberryIO;  
using Unosquare.RaspberryIO.Gpio;

namespace WebApi.Controllers  
{
    [Route("api/[controller]")]
    public class Max7219Controller : Controller
    {
        private GpioPin DataPin = Pi.Gpio.Pin00; // GPIO 17 (WiringPi pin num 0)  header pin 11
        private GpioPin ClockPin = Pi.Gpio.Pin03; // GPIO 22 (WiringPi pin num 3)   header pin 15
        private GpioPin LoadPin = Pi.Gpio.Pin04; // GPIO 23 (WiringPi pin num 4)   header pin 16

        private Dictionary<char, int> Characters = new Dictionary<char, int> 
        {
            {'-', 0b01000000},
            {'0', 0b01111110},
            {'1', 0b00110000},
            {'2', 0b01101101},
            {'3', 0b01111001},
            {'4', 0b00110011},
            {'5', 0b01011011},
            {'6', 0b01011111},
            {'7', 0b01110000},
            {'8', 0b01111111},
            {'9', 0b01111011},
            {'A', 0b01110111},
            {'B', 0b00011111},
            {'C', 0b01001110},
            {'D', 0b00111101},
            {'E', 0b01001111},
            {'F', 0b01000111},
            {'O', 0b00011101},
            {'R', 0b00000101},
            {' ', 0b00000000}
        };
        private int DECODE_MODE = 0x09;
        private int INTENSITY = 0x0a;
        private int SCAN_LIMIT = 0x0b;
        private int SHUTDOWN = 0x0c;
        private int DISPLAY_TEST = 0x0f;

        public Max7219Controller()
        {
            //We need 3 output pins to control the Max7219: Data, Clock and Load
            DataPin.PinMode = GpioPinDriveMode.Output;
            ClockPin.PinMode = GpioPinDriveMode.Output;
            LoadPin.PinMode = GpioPinDriveMode.Output;
        }

        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            Max7219Send(DISPLAY_TEST, 1);
            Max7219Send(DECODE_MODE, 0);   // Set BCD decode mode off
            Max7219Send(INTENSITY, 1);     // set brightness 0 to 15
            Max7219Send(SHUTDOWN, 1);      // come out of shutdown mode    / turn on the digits
            return new string[] { "Test mode. Call Max7219/{number} to show a number on the display" };
        }

        [HttpGet("{value}")]
        public string Get(int value)
        {
            /* 
            BCD decode mode off : data bits correspond to the segments (A-G and DP) of the seven segment display.
            BCD mode on :  0 to 15 =  0 to 9, -, E, H, L, P, and ' '
            */

            Max7219Send(DECODE_MODE, 1);   // Set BCD decode mode on
            Max7219Send(INTENSITY, 1);     // set brightness 0 to 15
            Max7219Send(SHUTDOWN, 1);      // come out of shutdown mode    / turn on the digits
            Max7219Send(1,value);

            /*
            var pin = Pi.Gpio.Pin00;
            pin.PinMode = GpioPinDriveMode.Output;
            pin.Write(value);
            return $"pin {pin.BcmPinNumber} set to {value}";
            */

            return $"sent {value} to Max7219";
        }


        /*
        GetFormatted() will set the value based on the first argument passed in. It will either display the hex or the decimal/integer value.
        http://servername/api/max7219/hex/10
        will display an "A"
         */
        [HttpGet("{format}/{value}")]
        public string GetFormatted(string format, int value)
        {
            Max7219Send(DISPLAY_TEST, 0);  // Disable test mode
            Max7219Send(INTENSITY, 0x01);     // set brightness 0 to 15
            Max7219Send(SHUTDOWN, 0x01);      // come out of shutdown mode    / turn on the digits
            Max7219Send(SCAN_LIMIT, 0x07);    // use all digits
            /* 
            BCD decode mode off : data bits correspond to the segments (A-G and DP) of the seven segment display.
            BCD mode on :  0 to 15 =  0 to 9, -, E, H, L, P, and ' '
            */

            Max7219Send(DECODE_MODE, 0);   // Set BCD decode mode off

            var outValue = format.ToLower() == "hex" ? value.ToString("X") : value.ToString();

            if (outValue.Length > 8)
            {
                // send error message
                outValue = "ERROR";
            }

            // make sure we have enough characters to work with
            outValue = outValue.PadLeft(8, ' ');
            var values = outValue.Reverse().Take(8).ToArray();

            for (int i = 0; i < 8; i++)
            {
                var outChar = values[i];
                Max7219Send(i + 1, Characters[outChar]);
            }

            return $"sent {outValue.Trim()} to Max7219 in {format} format.";
        }

        private void Max7219Send(int regNumber, int dataOut)
        {
            LoadPin.Write(GpioPinValue.High); // set LOAD High to start
            Send16Bits((regNumber << 8) + dataOut);   // send 16 bits ( reg number + dataout )
            LoadPin.Write(GpioPinValue.Low); // LOAD Low to latch
            LoadPin.Write(GpioPinValue.High); // set LOAD high to finish
        }

        private void Send16Bits(int output)
        {
            for(short i = 16; i > 0; i--)
            {
                int mask = 1 << (i - 1); // calculate bitmask

                ClockPin.Write(GpioPinValue.Low);

                // send one bit on the data pin
                if (Convert.ToBoolean(output & mask))
                {
                    DataPin.Write(GpioPinValue.High);
                }
                else
                {
                    DataPin.Write(GpioPinValue.Low);
                }

                ClockPin.Write(GpioPinValue.High);
            }
        }
    }
}

This code will allow you to use either decimal(integer) or hexadecimal values depending on how you call the method.

http://servername/api/max7219/hex/42

will display "2A" on the display, while

http://servername/api/max7219/decimal/42

will display "42".

Also, if the output data is more than 8 characters in length, it will display "Error" (line 113).
ERROR ERROR on the Max7219 8-character 7-segment display

Update - November 29, 2017 - Here are the hexadecimal digits for versions of C# prior to 7 that do not support the binary literals:

private Dictionary<char, int> Characters = new Dictionary<char, int>  
{
    {'0', 0x7e},
    {'1', 0x30},
    {'2', 0x6d},
    {'3', 0x79},
    {'4', 0x33},
    {'5', 0x5b},
    {'6', 0x5f},
    {'7', 0x70},
    {'8', 0x7f},
    {'9', 0x7b},
    {'A', 0x77},
    {'B', 0x1f},
    {'C', 0x4e},
    {'D', 0x3d},
    {'E', 0x4f},
    {'F', 0x47},
    {'O', 0x1d},
    {'R', 0x05},
    {'-', 0x40},
    {' ', 0x00}
};

Solved: Preventing Timeout error using XmlDocument.Load and SgmlReader

Written by Michael Earls
 programming  C#

I was working on a project that used the SgmlReader to clean up an invalid web page as I scraped data from it. I was using the System.Net.WebRequest class and related functionality.

However, because the page that I was calling used an xhtml DTD, yet included malformed xhtml in the document, it caused a timeout error when trying to load the document into an XmlDocument using the SgmlReader.

Here is my code (that caused a timeout error on line 21):

var req = WebRequest.Create("https://SomeWebsiteWithXhtmlDTDAndMalformedXhtml.com");

using (var res = req.GetResponse())  
{
  using (Stream responseStream = res.GetResponseStream())
  {
    using (StreamReader reader = new StreamReader(responseStream))
    {
      using (SgmlReader sgmlReader = new SgmlReader())
      {
        sgmlReader.DocType = "HTML";
        sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
        sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
        sgmlReader.InputStream = reader;

        // create document
        XmlDocument doc = new XmlDocument();
        doc.NameTable.Add("http://www.w3.org/1999/xhtml");
        doc.PreserveWhitespace = true;
        doc.XmlResolver = null;
        doc.Load(sgmlReader);
        return doc;
      }
    }
  }
}

Because of the malformed document (many of the tags were missing their closing tag - or specifically, one of the meta tags was missing it's ending slash. For example, rather than this:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

it used

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Notice that the last slash is missing, making this an invalid XHTML element. Even though SgmlReader is supposed to "fix" these types of issues, it seems that the DTD was causing the issue.

The fix involved breaking out the call to the web page from the WebRequest object to using the System.Net.WebClient class to grab the page as a string and read it in that way.

Here is the replacement code.

using (WebClient client = new WebClient())  
{
  string fipsDoc = client.DownloadString("https://SomeWebsiteWithXhtmlDTDAndMalformedXhtml.com");
  fipsDoc = fipsDoc.Substring(fipsDoc.IndexOf(Environment.NewLine) + Environment.NewLine.Length);

  StringReader reader = new StringReader(fipsDoc);

  using (SgmlReader sgmlReader = new SgmlReader())
  {
    sgmlReader.DocType = "HTML";
    sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
    sgmlReader.InputStream = reader;

    // create document
    XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = false;
    doc.XmlResolver = null;
    doc.Load(sgmlReader);
    return doc;
  }
}

The fix is in line #4 - I simply removed the first line of code from the file. That's where the DTD was being defined. I don't know for sure why it was causing a timeout, but I'm guessing it has something to do with the fact that SgmlReader was making assumptions about the content.

I'm a bit unhappy that I had to read it in as a string, manipulate it, then pass it through a StringReader, into the SgmlReader, and finally into the document, only then to get processed by my business logic. However, this solution works for my specific use case, so I'm not going to sweat it.


Controlling a 40106 Oscillator - Part 2

Written by Michael Earls
 programming  C#  electronics  synthesizers  schematics

In past blog entries (Controlling a 40106 Oscillator from Raspberry Pi), I have covered my adventures using the 40106 CMOS chip as an oscillator to create DIY synthesizers. Since I am a beginning electronics hobbyists (and I had limited supply of parts), my circuits were imperfect and completely wrong.

My main goal for now is to control the output of 40106 oscillators using a microcontroller (like the Raspberry Pi or the Arduino).

Note: Information about using 40106 and other CMOS chips to create DIY synthesizers can be found here: Intro to "Lunetta" CMOS Synths.

You can also find an enormous amount of information on the electro-music.com DIY Synth forum

The main problem I had in the previous attempt was that I was using a NAND gate with the pinout of the Raspberry Pi on one side of the gate and the oscillator output on the other side.

Here is a pseudo-schematic of my incorrect approach:

Incorrect circuit schematic

At first glance, this seemed OK, and my circuit appeared to work when I set Pin 7 on the Raspberry Pi to HIGH. However, I was making a mistake in two places.

  • Inverted output
  • Mixed input voltages to the NAND gate

Inverted Output

A layman's explanation of how the oscillator makes sound (because I am a layman)

The 40106, when setup with a capacitor and a resistor in a "feedback loop", creates a square wave by cycling on and off at a particular frequency. If the capacitor and resistor values are chosen carefully, the frequency of the oscillation is within human hearing (~20Hz to ~20kHz). You can then hookup the output of the oscillator to an audio amplifier and hear the sound that is generated. You can also use the same setup for a low frequency oscillator (LFO) outside of the human hearing range that can be used to control other aspects of your circuit.

I read over the math behind how this works and watched a few videos on YouTube, but it makes my brain melt, so I just hack away at it. Here is a much more detailed explanation (and some great plans for a finished Lunetta oscillator bank).

Here is a picture of my oscilloscope measuring an oscillator with a square wave within an audible range.

Square Wave on oscilloscope

When the square wave hits the high point (1), it sends a HIGH signal to the output. When the square wave hits the low point, it turns the signal off.

In my original setup, I used a 470nF capacitor and a 1MΩ resistor.

Since I was using a NAND gate, the signal went HIGH when the oscillator went low. So, I was actually "hearing" the bottom of the square wave!

The fix for this was simple, I simply bought some AND gates (CD4081B - datasheet). Then the output was HIGH when both inputs were HIGH. But, there was still a mismatch in the input voltages...

Mixed Input Voltages

In the schematic, notice that pin 14 (VDD/VCC) on both ICs is connected to the +5v output of the Raspberry Pi. The entire audio circuit is running at +5v. However, when the GPIO pin on the Raspberry Pi is HIGH, it is only supplying +3.3v to the logic gate (NAND in this example). So, one side of the logic gate is getting +5v, while the other is getting +3.3v. Like I said, the circuit was working, so I was happy. Upon further study I read that for the NAND gate to register a HIGH signal, the minimum voltage at the pin must be ~5v (since our source voltage was +5v). Also, it wasn't a good idea to connect the 3.3v GPIO pins directly to a circuit running at 5v.

Logic Level Shifter

Logic level shifter

I looked around and immediately found a logic-level shifter that I could buy that would convert my 3.3v outputs to a 5v output. I decided that they were too expensive for my application (I'm going to add many more 40106 oscillators to my setup). I may end up getting a few of these down the road for more passive and simplistic applications, but they don't suit my current needs.

Update: I still need a logic level shifter. Read more details below.

Enter the i2c Port Expander

After a little more digging, I found exactly what I was looking for. The MCP23017 i2c 16 input/output port Expander allows me to communicate with the gates using i2c (there is a similar version that uses the SPI interface if that's what you prefer).

MCP23017 i2c port expander

Each chip can control up to 16 oscillators by triggering the gate. Since the MCP23017 can run at 5v with the rest of the audio circuit, it will send a 5v HIGH signal to the gate when it is triggered. This solves my problem of worrying about GPIO pins having the wrong voltages.

Here is a link to an article on Adafruit explaining how to use the MCP23017 with the Pi. While the article is a bit dated, the concepts still hold true.

MCP230xx GPIO Expander on the Raspberry Pi

From the article:

Since these io expander chips use i2c to communicate, you can power them from 5V while still connecting the i2c data lines to a 3.3V device like the pi. That's because the Pi has two i2c resistors that pull up SDA/SCL to 3.3V.

Update: It turns out that the i2c also requires level-shifting from 3.3v to 5v. The great thing is that I only need one level-shifter for all of my i2c communications.

According to the MCP23017 datasheet (pg 28), the input pins need to have a minimum voltage of 0.8 VDD, which in my case is 5v.

So, I need to be sending at least 4v to the port expander. The fact that it's working with only 3.3v is a convenient quirk. As people have pointed out in the forums, this could lead to inconsistent results and failure when using other components.

I found a great article on this very topic: Raspberry Pi and I2C devices of different voltage

Here is the circuit that I need to level shift my i2c interface:

i2c logic level shifter circuit

There is a much better description of the level shifting application at Adafruit's website. Application Note AN97055 - Bi-Directional Level Shifter for I²C-bus and other systems

Update 2016-02-15: I found the perfect bi-directional logic level shifter on Amazon. These come in a 5 pack for around $9.

XCSOURCE 5PCS IIC I2C Logic Level Converter Bi-Directional Module 5V to 3.3V TE291

Here is my final schematic showing the MCP23017 port expander connected to the oscillator and the AND gate:

Schematic of a Gated Oscillator with MCP23017

You can see that there are only two wires coming from the Raspberry Pi. These are the i2c communication wires.

Here is a picture of this circuit on a breadboard:

Gated Oscillator circuit on a breadboard

The ICs (from left to right):

  • MCP23017 - i2c I/O Port Expander
  • CD4081BE - AND Gate
  • CD40106BE - Hex inverting Schmitt trigger (used as an oscillator)

The i2c lines can be seen at the bottom left of the screen (yellow and green wire pair).

Overview video

Platform, OS, and Development environment

You can use any microcontroller that supports i2c to make this work. I am using a Raspberry Pi with Windows 10 IoT edition. My code is written using Visual Studio 2015 and C# using the Adafruit .NET Class Library. This library has a class that supports communication with the MCP23017.

Note: I found the following resources necessary to get my Raspberry Pi running Windows 10 in developer mode and making the required settings:

  • Windows 10 IoT Start Page
  • Windows 10 IoT Core Dashboard -For setting up your Raspberry Pi to run Windows 10. Also allows for software project demo installs.
  • Windows Device Portal - This helped me set up developer mode and set the debug PIN. It also allows you to access the settings of the device.
  • Windows IoT Remote Display - This is the same thing as a remote desktop client for your Windows 10 IoT devices. It allows for autodiscovery of Windows 10 IoT devices on your network. I use it when debugging my app from Visual Studio on my PC. It displays my UI on the remote client. Combined with remote debugging in Visual Studio, it ticks all the boxes for being able to effectively debug and monitor a UWP app for Windows IoT.
  • Writing Apps

Most of the information above can be found from the home page for Windows 10 IoT. When all else fails, use your favorite search engine (and then follow the link it gives you to the answer on StackOverflow...)

Here is the main source code that runs the oscillator gate. The first section is the initialization logic. It runs when the application starts up:

private async void Init()
{
  try
  {
    // prepare the I2C for communication
    _mcp = new MCP23017(0x20); // 0x20 (decimal 32) is the default address
    await _mcp.InitMCP23017Async(i2cBase.i2cSpeed.i2c_400kHz);

    for (int outputPin = 0; outputPin < 16; outputPin++)
    {
      _mcp.pinMode(outputPin, MCP23017.Direction.OUTPUT);
    }

    PerformOutputTest();
  }
  catch (Exception ex)
  {
    string a = ex.Message;
  }
}

Once the initialization has occurred, the user interface loads up toggle switches. When the state of a toggle switch changes, it fires an event that determines the output pin based on the number of the toggle switch. Here is the toggle event handler:

private async void toggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
  var toggle = e.OriginalSource as ToggleSwitch;
  int outputPin = Int32.Parse(toggle.Name.Substring(Utility.TOGGLE_SWITCH_PREFIX.Length));

  MCP23017.Level toggleState = toggle.IsOn ? MCP23017.Level.HIGH : MCP23017.Level.LOW;

  try
  {
    _mcp.digitalWrite(outputPin, toggleState);
  }
  catch (Exception ex)
  {
    string a = ex.Message;
  }
}

The way I've implemented the handler, I have to take care to ensure that my toggle switch naming convention is handled correctly. In my case, I defined a constant value in a static utility class that I use to determine the name of the toggle switch.

Related: MCP23017 Class reference on Adafruit.com

Here is the definition of the prefix constant that is in my Utility class:

public const string TOGGLE_SWITCH_PREFIX = "toggleSwitch";

I have also named my toggle switches using this prefix and the target output pin that I want to flip when the switch state changes:

<ToggleSwitch 
  x:Name="toggleSwitch0" 
  Header="Gate 1" 
  HorizontalAlignment="Left" 
  Margin="10,65,0,0" 
  VerticalAlignment="Top" 
  Toggled="toggleSwitch_Toggled" 
  IsDoubleTapEnabled="False" 
  IsHoldingEnabled="False"  
/>

Here is what my user interface looks like on the Raspberry Pi:

When the user toggles the switch, the associated pin goes HIGH on the MCP23017, which causes the AND gate to toggle its output (pin 3 in this case) to HIGH each time the 40106 square wave goes HIGH. This output is then sent to the output pin (SIGNAL_OUT on the right side of the schematic), where it can be used by another circuit (an audio amplifier in this case).

Conclusion

After a few false starts, I believe that I have the gating mechanism that I can use to control most of my synth circuits. I anticipate that I'll also use this approach to turn effects on and off, as well as other applications (enabling/disabling control voltages (CV signals)).

Windows 10 IoT is Ready for Prime Time

I used Linux (Raspbian) and Mono .NET in my previous attempts at this effort. While it worked, it didn't feel comfortable. Things were off somehow.

I decided to switch to Windows 10 IoT. The Windows IoT ecosystem is absolutely brilliant. It was a little bit of a technical challenge getting things to work the first time, but everything performed exactly as it should have. The learning curve should be easy for most .NET developers and slightly challenging for non .NET developers. There were no strange errors or undocumented secrets to getting things to work.

The tools they provide "just work". I was able to get a remote shell on my Pi using PowerShell. I easily accessed my Pi using the IoT remote desktop app. It's easy to setup your custom app to always launch as the default app when the device starts. Add to that the fact that I can use Visual Studio 2015 (the IDE and development environment I use at work each day) to develop these apps and you have a great end-to-end solution. I haven't yet integrated with Azure IoT hub or any of the cloud features yet, but I have read up on them and know they could come in handy later for home automation and other applications.

Another great discovery was that Adafruit has created the .NET NuGet package (and related GitHub project). This made it very easy to interface with the MCP23017

Thanks go out to Rick Lesniak for his excellent work on this library. He saved me hours of work.

Footnote: I made videos describing each of the topics discussed in this post. I have not yet had the time to combine them into one video. Once I get it created and edited, I will embed it here and post a link to it on my social media sites.


Better property names using the DataMember attribute

Written by Michael Earls
 development  json  C#  .NET  serialization

In my previous post, I demonstrated creating a class to serialize the data returned from the Lipsum.com JSON feed. I wasn't happy with the final result as it used JavaScript formatting for the property names (camel cased).

I prefer Pascal casing on my object properties in C#, so I wanted to quickly show how to change the name of the property on the class.

Here is the new LoremIpsum class definition:

public class LoremIpsum
{
    public Feed Feed { get; set; }
}

[DataContract]
public class Feed
{
    [DataMember(Name ="lipsum")]
    public string Lipsum { get; set; }

    [DataMember(Name = "generated")]
    public string Generated { get; set; }

    [DataMember(Name = "donatelink")]
    public string DonateLink { get; set; }

    [DataMember(Name = "creditlink")]
    public string CreditLink { get; set; }

    [DataMember(Name = "creditname")]
    public string CreditName { get; set; }
}

You'll first need to add a reference to System.Runtime.Serialization to your project. Then, include the System.Runtime.Serialization namespace in your using declarations.

The main() method now looks like this:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2).Equals(0); // used this because markdown had trouble with double equal signs
        bool isThird = (i % 3).Equals(0);
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

The main difference is that now, we use LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum.

As you can see, our properties are now Pascal cased, so they look more in line with what you'll see throughout the other .NET libraries.


Getting filler text from the Lipsum.com REST API

Written by Michael Earls
 development  programming  C#  json  lorem ipsum

I had the need to generate some random filler text for a bunch of records today, and I wanted to use the Lorem Ipsum latin text. Normally, I use the great website Lipsum.com and fill out the form and hit submit. Then, I copy the text provided into my destination.

(This project (reusable .NET class library and sample app) can be found on GitHub at https://github.com/cerkit/LoremIpsum/)

However, I needed to automate this process, so I did a little poking around. It turns out that the lipsum.com website exposes a json feed that can be altered based on your needs.

Note: Using the Lipsum website in this manner is placing stress on their web server. As such, I highly suggest using the donate link provided within the data set that is returned to provide them with a little money to support your efforts.

I wrote my code in such a way as to limit the call rate to one call per second. It took a lot longer to insert my records than I wanted, but I felt sure I wasn't putting unneeded strain on their servers.

The main endpoint for accessing the default data set is: http://lipsum.com/feed/json.

This will give you the following results:

{
    feed: {
        lipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tristique massa eu porttitor aliquam. Vivamus sodales sit amet nulla nec volutpat. Sed accumsan iaculis turpis, maximus sagittis ipsum tincidunt et. Cras ac velit eu quam cursus lobortis sit amet vitae quam. Donec nec odio at ligula porttitor viverra nec eu est. Praesent non quam ipsum. Curabitur vitae scelerisque augue. In sed elementum velit. Donec lacinia ut leo a porttitor. Phasellus nec risus placerat, pulvinar ante euismod, tempus lacus. Nam turpis velit, accumsan eget placerat porttitor, hendrerit vitae tortor. Vivamus posuere leo elit, at pretium justo imperdiet id. Duis finibus ante vel mollis rhoncus. Donec sollicitudin sed tortor vulputate bibendum. Aenean tincidunt nisi sed libero sollicitudin, in interdum erat efficitur. Phasellus porttitor faucibus risus non consectetur. Nam a sollicitudin erat, ut lacinia leo. Praesent convallis odio orci, a iaculis lacus viverra non. Maecenas consequat, risus nec egestas consectetur, tellus tellus condimentum mi, in suscipit metus sem quis velit. In a lorem semper, tincidunt mauris a, blandit erat. Aliquam non auctor tortor, et mattis nibh. Aenean at magna at diam commodo feugiat sit amet ut erat. Nunc hendrerit tempus imperdiet. Phasellus varius id justo non vestibulum. Ut quis mollis mauris. Aliquam egestas arcu non erat congue, id ornare elit molestie. Pellentesque rutrum nunc sed arcu semper mollis. Proin malesuada tristique quam quis luctus. Nunc dignissim, orci vitae rhoncus porta, orci enim accumsan urna, ut egestas metus lectus id turpis. Sed in nisi ligula. Etiam sodales est arcu, vitae dignissim metus blandit id. Aenean leo velit, blandit sit amet ex vel, vestibulum ornare ipsum. Donec rutrum euismod velit, ac fringilla leo iaculis ornare. Duis a eros id odio aliquet vestibulum quis vel est. Sed ultricies ac sapien sed tincidunt. Integer bibendum turpis at nisl venenatis facilisis. Morbi sodales dignissim lectus, non sagittis purus cursus dignissim. Phasellus aliquam elementum venenatis. Nunc sed pharetra purus, id blandit velit. In sed massa consequat, posuere nulla non, rhoncus orci. Maecenas a consequat lorem. Morbi sit amet quam felis. Sed at posuere metus. Morbi vestibulum nisl id massa euismod malesuada. Aenean accumsan, elit eu finibus pellentesque, elit metus faucibus tellus, non interdum lacus massa ut velit. Suspendisse fermentum elit sed ipsum luctus consequat. Suspendisse potenti. Aenean sagittis lorem augue, quis condimentum velit facilisis eu. Vivamus posuere ante sed porta fringilla. Morbi pharetra lorem id urna iaculis cursus. Pellentesque at arcu vel lacus euismod accumsan. Sed pretium turpis odio, id tincidunt nisi blandit nec. Suspendisse non ornare massa. Proin facilisis porta dolor nec vestibulum. Aenean accumsan pulvinar magna, in auctor odio tempor eget. Morbi in rutrum quam. Fusce quis ipsum augue. Duis et ligula ut tellus sollicitudin rutrum sit amet eget nisi. Duis id est sit amet orci venenatis consectetur et eget ipsum.",
        generated: "Generated 5 paragraphs, 454 words, 3017 bytes of Lorem Ipsum",
        donatelink: "http://www.lipsum.com/donate",
        creditlink: "http://www.lipsum.com/",
        creditname: "James Wilson"
    }
}

I decided to take a look at the source code for the home page and get an idea of the form names that are used to set the options for the feed.

I found the following query string arguments

  • what: valid values = paras, words, bytes, and lists
  • amount: the amount of the chosen type to return (the minimum value is 5 for words)
  • start: yes or no depending on whether or not you want to start with "Lorem Ipsum". If set to no, you'll get a random return value.

So, I wrote my program to loop through the days in the current year and insert a record for each day, adding the random "lipsum" text to the record.

Here's a quick C# program that will use the Newtonsoft.Json library to deserialize the lipsum result into an object that you can use in your code.

This assumes that you're using Visual Studio (community or professional edition).

First, visit the following url: http://lipsum.com/feed/json?amount=5&start=no&what=words

Now, view the source of the results and copy them to your clipboard. Start a new project in Visual Studio (if you don't already have one open) and then create a new class. Name the file LoremIpsum.cs.

It will generate the following code:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;

namespace LoremIpsum  
{
    class LoremIpsum
    {
    }
}

Delete the class LoremIpsum that it generated (but keep the rest of the file).

Click inside the namespace and choose Edit->Paste Special->Paste JSON as Classes from the main menu.

This will insert classes that are compatible with the lipsum data. Rename the Rootobject class to LoremIpsum. Your code should look like the following (LoremIpsum.cs):

namespace LoremIpsum  
{
    public class LoremIpsum
    {
        public Feed feed { get; set; }
    }

    public class Feed
    {
        public string lipsum { get; set; }
        public string generated { get; set; }
        public string donatelink { get; set; }
        public string creditlink { get; set; }
        public string creditname { get; set; }
    }

}

Now, we will need to fetch the data and deserialize it into an object we can use.

Before we continue, make sure you have a reference to the Newtonsoft.Json library. You can use nuGet to install it easily.

First, we'll define an enum to represent the result types:

public enum LipsumType  
{
    [Description("words")]
    Words,
    [Description("paras")]
    Paragraphs,
    [Description("bytes")]
    Bytes,
    [Description("lists")]
    Lists
}

Notice that I used the System.ComponentModel.Description attribute on each of the enum values to represent the values that need to get sent to the api. This will come in handy later.

Here is a generic extension method on enums that will return the description (this works on any enum containing values decorated with the System.ComponentModel.DescriptionAttribute class):

public static string GetDescription(this T e) where T : IConvertible  
{
    Array values = System.Enum.GetValues(e.GetType());
    string description = null;

    foreach (int val in values)
    {
        if (val == e.ToInt32(CultureInfo.InvariantCulture))
        {
            var type = e.GetType();
            var memInfo = type.GetMember(Enum.GetName(type, val));
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            description = ((DescriptionAttribute)attributes[0]).Description;
        }
    }

    return description;
}

Now, let's move on to the actual web call:

public static readonly string LIPSUM_JSON_URL = "http://lipsum.com/feed/json?amount={0}&start={1}&what={2}";

public static LoremIpsum GetNewLipsum(LipsumType lipsumType, int amount, bool startWithLoremIpsum = true, ICredentials proxyCredentials = null)  
{
    string requestUrl = string.Format(LIPSUM_JSON_URL, amount, startWithLoremIpsum ? "yes" : "no", lipsumType.GetDescription());

    HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;

    if (proxyCredentials != null)
    {
        request.Proxy.Credentials = proxyCredentials;
    }

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(String.Format(
            "Server error (HTTP {0}: {1}).",
            response.StatusCode,
            response.StatusDescription));

        StreamReader sr = new StreamReader(response.GetResponseStream());
        JsonTextReader tr = new JsonTextReader(sr);
        JsonSerializer ser = new JsonSerializer();

        return ser.Deserialize(tr);
    }
}

In the requestUrl definition, I used the LipsumType.GetDescription() extension method that I defined earlier to send the correct type based on what was chosen by the caller.

Don't forget to use the using() {} when dealing with an object that implements IDisposable. It will clean up after you and prevent you from leaving any machine resources open.

Notice the use of the ser.Deserialize<LoremIpsum>() call (GitHub source). I was able to do this because we created a class directly from the JSON data. We then use this class with the Json (de)serializer to get an instance of the LoremIpsum class containing the results of our call.

Here is the main() method of the program that ties it all together:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2) == 0;
        bool isThird = (i % 3) == 0;
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).feed.lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

This simply loops 10 times and makes a call to the lipsum.com json endpoint, toggling between paragraphs and words, as well as starting with "Lorem Ipsum" every third call. It also waits one second between each call to be friendly to the server.

Because we get back a fully populated object, we can also access the other properties on the LoremIpsum instance, like *.feed.generated and *.feed.donatelink.

Update: I've written a post that describes how to get PascalCased property names.


Decorating an enum with the Description attribute for later use in C# with .NET

Written by Michael Earls
 .NET  C#

I had the need today to set a string value based on the value of an enum. Rather than creating the following code:

Edit: I added a generic method that works on all enums

string myString = null;  
switch(myEnum)  
{
    case myEnum.Value1: 
        myString = "value 1"; 
        break; 
    case myEnum.Value2: 
        myString = "value 2"; 
        break; 
    case myEnum.Value3: 
        myString = "value 3"; 
        break; 
}

I wanted to do something simpler. So, I decided to add the System.ComponentModel.Description attribute to my enum, like so:

using System.ComponentModel; 

public enum MyEnum  
{ 
    [Description("value 1")] 
    Value1, 
    [Description("value 2")]
    Value2, 
    [Description("value 3")]
    Value3
}

Then, to make it easy to use, I added an extension method to all enums:

public static string GetDescription<T>(this T e) where T : IConvertible  
{
    string description = null;

    if (e is Enum)
    {
        Type type = e.GetType();
        Array values = System.Enum.GetValues(type);

        foreach (int val in values)
        {
            if (val == e.ToInt32(CultureInfo.InvariantCulture))
            {
                var memInfo = type.GetMember(type.GetEnumName(val));
                var descriptionAttributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if(descriptionAttributes.Length > 0)
                {
                    // we're only getting the first description we find
                    // others will be ignored
                    description = ((DescriptionAttribute)descriptionAttributes[0]).Description;
                }

                break;
            }
        }
    }

    return description;
}

This will allow you to easily get the description of the current enum value. Here is how you would do that:

string description = null;  
MyEnum testEnum = MyEnum.Value2;  
description = testEnum.GetDescription(); // description will be "value 2"

As you can see, it’s pretty easy to decorate your enum values with string descriptions. This allows you to have a central location to set the value.

I can even see a custom description attribute class that retrieves the description from a database. The use cases are there.

Another, more common use case for this method is to localize the values returned by using resource files representing the languages you want to display. You could have one for en-US, en-GB, es-ES, es-MX, etc, using the description Name as the key to the resource file.


Project changes! More C# posts to come

Written by Michael Earls
 C#  VB.NET

After a meeting this morning, we have decided to go with ASP.NET 5 and C#, rather than ASP.NET 4.5.2 and Visual Basic .NET. So, my technical posts will switch back to C#.

I’m pretty excited about the change. I had the base framework completed in VB, but that would have ensured that my client would be stuck in the near future as Microsoft is not supporting VB in the next version of ASP.NET.

Now, the dilemma is whether or not to use AngularJS. :)