0

C# call circuitpython function
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

C# call circuitpython function

by pedrocsc21 on Thu Nov 01, 2018 6:39 pm

I am very new to this and am working on a C# application that I want to send a value to the main.py file in the circuitpython code. This value will be used to trigger turn on and off a light. The current problem is that I can not seem to find anything online where some kind of example is explaining how to do this exactly. I assume I have communication through the a port and call a function in the circuitpython code but again I really have no clue where to start. Any help is much appreciated.

pedrocsc21
 
Posts: 3
Joined: Thu Nov 01, 2018 6:01 pm

Re: C# call circuitpython function

by adafruit_support_mike on Sat Nov 03, 2018 2:41 am

[moved to the CircuitPython forum]

adafruit_support_mike
 
Posts: 57493
Joined: Thu Feb 11, 2010 2:51 pm

Re: C# call circuitpython function

by suffen on Sat Nov 03, 2018 3:27 am

Hi,

I've not used C# to communicate with a Circuitpython board before but I think you've got the right idea. You have to figure out how to send Serial UART communication on C# to -> Circuitpython COM port.

Perhaps these links can give you a start:
https://learn.adafruit.com/circuitpython-essentials/circuitpython-uart-serial
https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport

suffen
 
Posts: 19
Joined: Mon Jun 19, 2017 4:47 pm

Re: C# call circuitpython function

by kevinjwalters on Sun Nov 04, 2018 7:15 pm

If you can accept the blocking behaviour you can just use input() on the CPX board to read data from the host computer.

kevinjwalters
 
Posts: 373
Joined: Sun Oct 01, 2017 3:15 pm

Re: C# call circuitpython function

by pedrocsc21 on Tue Nov 06, 2018 7:21 pm

kevinjwalters wrote:If you can accept the blocking behaviour you can just use input() on the CPX board to read data from the host computer.


how do you go about doing that?

pedrocsc21
 
Posts: 3
Joined: Thu Nov 01, 2018 6:01 pm

Re: C# call circuitpython function

by pedrocsc21 on Thu Nov 08, 2018 7:21 pm

I figured it out. I wrote my main.py file to wait for the input it needed to turn on or off the switch hooked up to pin5, this signal comes from my c# application through serial port communication. In my c# application I look for the port being used by my usb device by using the VID and PID (vendor id, and product id set by the manufacture), i then send that COM port to start a new SerialPort connection and then set my serialport settings according to what the COM port has listed for that device. Hope this helps anyone else out there.

Code: Select all | TOGGLE FULL SIZE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.IO.Ports;
using System.Management;


namespace MySerialPortProgram
{
    SerialPort serPort = new SerialPort();

    public MainWindow()
    {
        // Find the port of usb device
        string port = FindPort();
        // Connect to port
        serPort = SerialConnect(port);

        // Send command to main.py which is waiting for signal
        // ex: 1 = turn on,  0 = turn off
        SendCommand(serPort, "1");
    }

    private string FindPort()
    {
        string portName = "";
        // Specific DIV and PID info from USB device
        List<string> names = ComPortNames("239A", "801F");
        // List of all ports connected
        string[] ports = SerialPort.GetPortNames();

        if (names.Count > 0)
        {
            foreach (string s in ports)
            {
                if (names.Contains(s))
                {
                    Console.WriteLine("My USB port is " + s);
                    portName = s;
                }
            }
        }
        else
        {
            Console.WriteLine("No COM ports found");
        }

        return portName;
    }

    private List<string> ComPortNames(String VID, String PID)
    {
        String pattern = String.Format("^VID_{0}.PID_{1}", VID, PID);
        Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
        List<string> comports = new List<string>();
        RegistryKey rk1 = Registry.LocalMachine;
        RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");
        foreach (String s3 in rk2.GetSubKeyNames())
        {
            RegistryKey rk3 = rk2.OpenSubKey(s3);
            foreach (String s in rk3.GetSubKeyNames())
            {
                if (_rx.Match(s).Success)
                {
                    RegistryKey rk4 = rk3.OpenSubKey(s);
                    foreach (String s2 in rk4.GetSubKeyNames())
                    {
                        RegistryKey rk5 = rk4.OpenSubKey(s2);
                        RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");
                        if (!((string)rk6.GetValue("PortName") == "" || (string)rk6.GetValue("PortName") == null))
                        {
                            comports.Add((string)rk6.GetValue("PortName"));
                        }
                    }
                }
            }
        }

        return comports;
    }

    private SerialPort SerialConnect(string portName)
    {
        Console.WriteLine("Connecting to Port: " + portName);
        // Create the serial port with the needed settings from the usb device
        SerialPort sp = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
        sp.Handshake = Handshake.XOnXOff;
        sp.DtrEnable = true;
        sp.ReadTimeout = 500;
        sp.WriteTimeout = 500;

        // Attach a method to be called when there is data waiting in the port's buffer
        sp.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
        sp.ErrorReceived += new SerialErrorReceivedEventHandler(SerialPort_ErrorReceived);

        //Open the communication line
        sp.Open();

        return sp;
    }

    private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
    {
        SerialPort ser = sender as SerialPort;
        // Show all the incoming data in the port's buffer
        Console.WriteLine("SerPort_ErrorReceived " + ser.ReadExisting());
    }

    private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort ser = sender as SerialPort;
        // Show all the incoming data in the port's buffer
        Console.WriteLine("SerialPort_DataReceived " + ser.ReadExisting());
    }

    private void SendCommand(SerialPort serial, string command)
    {
        Console.WriteLine("SendCommand: " + command);
        try
        {
            command = command + "\r";
            serial.Write(command);
        }
        catch { }
    }
}


This is a barebone example of main.py
Code: Select all | TOGGLE FULL SIZE
import board
import digitalio
import time
 
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
 
while True:
     simTrigger()


def simTrigger():
    """Simulates input trigger"""
    print("Send 1 to turn on and 0 to turn off")
    level = input("Please enter value: ")
    print("Value entered is: ", level)
    #write your code to do whatever you want it to do here

pedrocsc21
 
Posts: 3
Joined: Thu Nov 01, 2018 6:01 pm

Re: C# call circuitpython function

by kevinjwalters on Sun Nov 11, 2018 12:52 pm

I found the test code I wrote, no real difference to yours:

Code: Select all | TOGGLE FULL SIZE
from adafruit_circuitplayground.express import cpx

colour = {
 "red"   : (0x20, 0, 0),
 "green" : (0, 0x20, 0),
 "blue"  : (0, 0, 0x20),
}

while True:
    command = input()
    try:
        [verb, noun] = command.split()
        if verb == "glow":
            cpx.pixels.fill(colour[noun])
            continue
    except:
        pass  ### fall through to error handling
    print("unknown command: " + command)

kevinjwalters
 
Posts: 373
Joined: Sun Oct 01, 2017 3:15 pm

Re: C# call circuitpython function

by kevinjwalters on Sat Jan 12, 2019 10:32 am

If you want to avoid blocking, 3.1.2 has a new feature which allows you to check if there's anything waiting in the buffers to read with input(), runtime.serial_bytes_available: https://blog.adafruit.com/2019/01/06/ci ... uitpython/

kevinjwalters
 
Posts: 373
Joined: Sun Oct 01, 2017 3:15 pm

Please be positive and constructive with your questions and comments.