Initial commit

master
Jonas Arnold 3 years ago
commit 5e49ddeb14
  1. 25
      udp_led_test_app/Dockerfile
  2. 1
      udp_led_test_app/build.sh
  3. 1
      udp_led_test_app/run.sh
  4. 12
      udp_led_test_app/src/BAT_UdpLedTestApp.csproj
  5. 55
      udp_led_test_app/src/Joystick.cs
  6. 17
      udp_led_test_app/src/JoystickButtons.cs
  7. 14
      udp_led_test_app/src/LedColor.cs
  8. 94
      udp_led_test_app/src/Leds.cs
  9. 118
      udp_led_test_app/src/Program.cs

@ -0,0 +1,25 @@
#FROM debian
# file: Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder
WORKDIR /app
# Copy everything from src-directory on host to workdir in image
COPY src .
# Build and publish a release to directory "out" (build implicitly restores NuGet packages)
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/runtime:7.0
# install GPIO library (don't clean, need cache :-)
RUN apt-get -y update && apt-get -y install gpiod libgpiod2 libgpiod-dev
# set build- and run-time working directory
WORKDIR /app
COPY --from=builder /app/out /app
CMD ["dotnet", "/app/BAT_UdpLedTestApp.dll"]

@ -0,0 +1 @@
docker build . -t udp_led_test_app

@ -0,0 +1 @@
docker run --rm -it --device /dev/gpiochip0 -p 10001:10001/udp udp_led_test_app

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Iot.Device.Bindings" Version="2.1.0" />
</ItemGroup>
</Project>

@ -0,0 +1,55 @@
using System;
using System.Device.Gpio;
using System.Device.Gpio.Drivers;
namespace BAT_UdpLedTestApp {
internal class Joystick {
// public event EventHandler<JoystickEventArgs> JoystickChanged;
protected int buttonLeft = 6;
protected int buttonRight = 5;
protected int buttonUp = 19;
protected int buttonDown = 13;
protected int buttonCenter = 26;
private static GpioController Ctrl { get { return Program.Ctrl; } }
private static Joystick joystick = null;
public static Joystick GetInstance() {
if( joystick == null ) {
joystick = new Joystick();
}
return joystick;
}
private Joystick() {
if( Ctrl == null )
throw new Exception( "Constructor Joystick needs access to GpioController object." );
Console.WriteLine( "in Joystick() - Initializing Pins" );
Ctrl.OpenPin( buttonLeft, PinMode.Input );
Ctrl.OpenPin( buttonRight, PinMode.Input );
Ctrl.OpenPin( buttonUp, PinMode.Input );
Ctrl.OpenPin( buttonDown, PinMode.Input );
Ctrl.OpenPin( buttonCenter, PinMode.Input );
} // end constructor
public JoystickButtons State {
get {
JoystickButtons state = JoystickButtons.None;
// PinValue v = ctrl.Read( buttonLeft );
if( Ctrl.Read( buttonLeft ) == false ) state |= JoystickButtons.Left;
if( Ctrl.Read( buttonRight ) == false ) state |= JoystickButtons.Right;
if( Ctrl.Read( buttonUp ) == false ) state |= JoystickButtons.Up;
if( Ctrl.Read( buttonDown ) == false ) state |= JoystickButtons.Down;
if( Ctrl.Read( buttonCenter ) == false ) state |= JoystickButtons.Center;
return state;
}
} // property State
} // end class Joystick
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAT_UdpLedTestApp {
[Flags]
public enum JoystickButtons {
None = 0,
Left = 1,
Right = 2,
Up = 4,
Down = 8,
Center = 16
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAT_UdpLedTestApp {
public enum LedColor {
Green,
Yellow,
Red,
Blue
}
}

@ -0,0 +1,94 @@
using System;
using System.Device.Gpio;
using System.Threading;
namespace BAT_UdpLedTestApp {
public class Leds {
// APROG HAT rev6 // rev7
int pinLedRed = 21; // 16
int pinLedYellow = 20; // 20
int pinLedGreen = 16; // 21
int pinLedBlue = 12; // n/A - set to one of the others!
bool stateLedRed = false; // PinValue.Low
bool stateLedYellow = false;
bool stateLedGreen = false;
bool stateLedBlue = false;
private static GpioController Ctrl { get { return Program.Ctrl; } }
private static Leds leds = null;
public static Leds GetInstance() {
if( leds == null ) {
leds = new Leds();
}
return leds;
}
private Leds() {
if( Ctrl == null )
throw new Exception( "Constructor Leds needs access to GpioController object." );
// set GPIO to output mode
Ctrl.OpenPin( pinLedRed, PinMode.Output );
Ctrl.OpenPin( pinLedYellow, PinMode.Output );
Ctrl.OpenPin( pinLedGreen, PinMode.Output );
Ctrl.OpenPin( pinLedBlue, PinMode.Output );
// breifly flash Leds: switch all Leds on
Ctrl.Write( pinLedRed, PinValue.High );
Ctrl.Write( pinLedYellow, PinValue.High );
Ctrl.Write( pinLedGreen, PinValue.High );
Ctrl.Write( pinLedBlue, PinValue.High );
Thread.Sleep( 50 );
// switch all Leds off
Ctrl.Write( pinLedRed, PinValue.Low );
Ctrl.Write( pinLedYellow, PinValue.Low );
Ctrl.Write( pinLedGreen, PinValue.Low );
Ctrl.Write( pinLedBlue, PinValue.Low );
} // end constructor
public bool Get( LedColor color ) {
// horrible spaghetti code!help me fix it!;)
switch( color ) {
case LedColor.Red:
return stateLedRed;
case LedColor.Yellow:
return stateLedYellow;
case LedColor.Green:
return stateLedGreen;
case LedColor.Blue:
return stateLedBlue;
default:
throw new NotImplementedException( "Unknown LedColor " + color );
}
}
public void Set( LedColor color, bool state ) {
// horrible spaghetti code! help me fix it! ;)
switch( color ) {
case LedColor.Red:
stateLedRed = state;
Ctrl.Write( pinLedRed, (PinValue)stateLedRed );
break;
case LedColor.Yellow:
stateLedYellow = state;
Ctrl.Write( pinLedYellow, (PinValue)stateLedYellow );
break;
case LedColor.Green:
stateLedGreen = state;
Ctrl.Write( pinLedGreen, (PinValue)stateLedGreen );
break;
case LedColor.Blue:
stateLedBlue = state;
Ctrl.Write( pinLedBlue, (PinValue)stateLedBlue );
break;
default:
throw new NotImplementedException( "Unknown LedColor " + color );
}
} // end Set()
} // end class Leds
} // end namespace

@ -0,0 +1,118 @@
using System;
using System.Threading;
using System.Device.Gpio;
using System.Device.Gpio.Drivers;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace BAT_UdpLedTestApp {
internal class Program {
public static GpioController Ctrl { get; set; }
static void Main( string[] args ) {
Console.WriteLine( "Application started!" );
// Set up GPIO
int gpioBank = 0;
Console.WriteLine( "in Joystick() - create LibGpiodDriver" );
LibGpiodDriver libGpiodDriver = new LibGpiodDriver( gpioBank );
Console.WriteLine( "in Joystick() - create GpioController" );
GpioController ctrl = new GpioController( PinNumberingScheme.Logical, libGpiodDriver );
Ctrl = ctrl; // set in public property so joystick and leds can access it
Thread t = new Thread( Run );
// Background thread, ends when Main() ends
t.IsBackground = false;
t.Start();
// Program ends, but Run-Thread keeps working
}
protected static void Run() {
Joystick joystick = Joystick.GetInstance();
Leds leds = Leds.GetInstance();
JoystickButtons oldState = JoystickButtons.None;
JoystickButtons newState;
IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, 10001);
UdpClient udpClient = new UdpClient(ipEndpoint);
udpClient.Client.ReceiveTimeout = 100; // set timeout to 100ms
byte[] data = new byte[1024];
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("Waiting for clients...");
while( true ) {
// reset array
data = Array.Empty<byte>();
// try receive data
try
{
data = udpClient.Receive(ref sender);
}
catch (SocketException sockEx)
{
// timeout = normal use case
if (sockEx.SocketErrorCode != SocketError.TimedOut)
{
throw;
}
}
// decode message, if any received => Handle it
string receivedMessage = Encoding.ASCII.GetString(data, 0, data.Length);
if(receivedMessage.Length > 0)
{
Console.WriteLine("Message received from {0}:", sender.ToString());
Console.WriteLine(receivedMessage);
if(receivedMessage.StartsWith("led on"))
{
leds.Set( LedColor.Green, true );
ReplyMessage(udpClient, sender, "Led turned on");
}
else if(receivedMessage.StartsWith("led off"))
{
leds.Set( LedColor.Green, false );
ReplyMessage(udpClient, sender, "Led turned on");
}
else if(receivedMessage.StartsWith("joystick state"))
{
JoystickButtons state = joystick.State;
ReplyMessage(udpClient, sender, $"Current Joystick state: {state}");
}
else
{
ReplyMessage(udpClient, sender, "Unknown command");
}
}
// check if the joystick state changed, send to last sender
newState = joystick.State;
if( oldState != newState ) {
Console.WriteLine($"New Joystick state detected: {newState}");
ReplyMessage(udpClient, sender, $"New Joystick state: {newState}");
oldState = newState;
}
Thread.Sleep( 50 );
}
}
public static void ReplyMessage(UdpClient client, IPEndPoint sender, string replyMessage)
{
// would lead to exception
if(sender.Address == IPAddress.Any) { return; }
// terminate message with LF
string terminatedMessage = $"{replyMessage}\n";
// send data
byte[] data = new byte[1024];
data = Encoding.ASCII.GetBytes(terminatedMessage);
client.Send(data, data.Length, sender);
Console.WriteLine($"Sent message: {replyMessage}");
}
} // end class Program
} // end namespace
Loading…
Cancel
Save