Arduino - C# = USB

Hi

I have almost reach to the end of testing Arduino for my project. If you are looking bellow you can see that the outcomming stream from Arduino is is like:
D0-(1-9)=(0/1)
D(10-53)=(0/1)

The Arduino are sending a stream containing all the states for each digital pins, see the code bellow:

My sketch for the Arduino board (loop function):

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

  // Set pinMode for the board pins ===========================================
 .....................
  // ==========================================================================
}

void loop()
{ 
  // Declaration of containers
  String controlStr, controlStrType, controlStrPinType, controlStrPin, controlStrBool, readString;
  
  // ======================== Save the (input / input_pullupp ) pinstates in an array of lenght = 54 ===============================
    int pinStatesArr[54];
    for (int i = 0; i < pinAmount; i = i + 1){
      if(i == 0 || i == 1) pinStatesArr[0] = -1;
      else pinStatesArr[i] = digitalRead(digitalPinsArr[i]);
    }
  
  // ======================== Write state of the changing pin 
// If loopIndex is  bellow 10 add a zero next to 2-53
  if(loopIndex < 10){
    if(pinStatesArr[loopIndex] == 0) Serial.println(String('D')+String('0')+loopIndex+String("=0"));  // Opened = INPUT_PULLUP = 0
    if(pinStatesArr[loopIndex] == 1) Serial.println(String('D')+String('0')+loopIndex+String("=1")); // Closed = INPUT_PULLUP = 1 
  }
  if(loopIndex >= 10){
    if(pinStatesArr[loopIndex] == 0) Serial.println(String('D')+loopIndex+String("=0"));  // Pin = Opened = INPUT_PULLUP = 0

    if(pinStatesArr[loopIndex] == 1) Serial.println(String('D')+loopIndex+String("=1"));  // Pin =   while(Serial.available()){
    delay(1);
    if(Serial.available()>0){
      char incommingString = Serial.read();
      if(isControl(incommingString)){
        break;
      }
        // Save the string and add the new one 
        readString += incommingString;
        // Save the string in more of a global container reacheable further 
         controlStr = readString;
     }
  }  
  loopIndex++; 
  if (loopIndex == pinAmount) loopIndex = 0;
}

Inside the C# program is a while loop tha will handle the string (serialPort.ReadLine())

My class for "ConnectionArduinoD1" (C# side):

using ....

namespace FSPanel_App___Backend
{
    class ConnectionArduinoD1
    {
        static string type;
        static string pinNr;
        static string  pinState;
        static string[] boardsPinstates = new string[]{
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state",
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state",
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state" };
        static bool firstRunOpen = true;
        static bool connect;
        static SerialPort serialPort;
        public static void BoardStart()
        {
            Thread readThread = new Thread(Read);
            serialPort = new SerialPort();
            OpenSerialPort();
            Console.WriteLine($"Connected to port {serialPort.PortName} at {serialPort.BaudRate} baud.");
            readThread.Start();
        }
        public static void Read()
        {
            while (connect)
            {
                try
                {
                    var message = serialPort.ReadLine();
                    Console.WriteLine(message);
                    SplitString(message);
                    if (message == "D2=Open\r") boardsPinstates[2] = "Open";
                    if (message == "D2=Close\r") boardsPinstates[2] = "Close";
                    if (message == "D7=Open\r") boardsPinstates[7] = "Open";
                    if (message == "D7=Close\r") boardsPinstates[7] = "Close";
                    
                    Switch3Poss();
                }
                catch (TimeoutException) { }
                firstRunOpen = false;
                
                //serialPort.WriteLine("");
            }
        }
        private static void SplitString(string messagesSplit)
        {
            type = messagesSplit.Substring(0, 1);
            pinNr = messagesSplit.Substring(1, 2);
            pinState = messagesSplit.Substring(4, 1);
        }
            private static void Switch3Poss()
        {
            /*Control string for Arduinos component commands. There are different typ according the components. It starts = inp/out
                inp:
                    Switch - 2 / 3 poss (Middle poss = 

                out: 

            _a/d_01-53_1/0
            */
            if (boardsPinstates[2] == "Open" && boardsPinstates[7] == "Close") {
                serialPort.WriteLine("out_d_10_1");
            }
            if(boardsPinstates[2] == "Close" && boardsPinstates[7] == "Close")
            {
                serialPort.WriteLine("out_d_11_1");     
                firstRunOpen = false;  
            }
            if(boardsPinstates[2] == "Close" && boardsPinstates[7] == "Open")
            {
                serialPort.WriteLine("out_d_10_0");
                serialPort.WriteLine("out_d_11_0");
            }
        }
        private static void OpenSerialPort()
        {
            serialPort.PortName = "Com4";
            serialPort.BaudRate = 9600;
            serialPort.ReadTimeout = 5000;
            serialPort.WriteTimeout = 5000;
            serialPort.Open();
            connect = true;
            
            Console.WriteLine($"Connected to port {serialPort.PortName} at {serialPort.BaudRate} baud.");
        }
    }
}

All works fine but I will add additional behavior. I need a funktion in Arduino that will immediately send the current pinstate of the changing ping. I have search for it and ask in a forum. I was told that I need some sort of "interrupt" function
-->

You have a table next to hte first text subparagraph for "Mega, Mega2560, MegaADK" you can read that this function just work for digitalpins "2, 3, 18, 19, 20, 21".

It causing a problem since I have about 30 switches for almost every boards.

The question is am I able to find a solutions so I can use Arduino?

Look at the txt file :slight_smile:

Best regards Fredrik

Code.txt (10.1 KB)

FredrikH:
From Arduino the strings are creating inside from the main loop function. Inside the C# program is the opposite the stream (serialPort.ReadLine()) are taking care of inside the while loop. Therefore you
need a funktion in Arduino that will immediately send the current pinstate of the changing ping.

Sorry, but I can't make sense of that.

You say the Arduino is sending some data to the PC. Are you saying that it is sending the wrong data or that it needs to send some additional data?

And your attachment in your Original Post contains two programs. If you post them separately they will each be small enough so you can include them in your Posts where people can access them more easily. Please use the code button </>. See How to use the forum

...R

Robin2:
Sorry, but I can't make sense of that.

You say the Arduino is sending some data to the PC. Are you saying that it is sending the wrong data or that it needs to send some additional data?

And your attachment in your Original Post contains two programs. If you post them separately they will each be small enough so you can include them in your Posts where people can access them more easily. Please use the code button </>. See How to use the forum

...R

I have edit the topic, skip the included file :slight_smile:

Thank you for updating your Post and clarifying things - even though my Reply #1 now makes little sense.

To my mind you are making things very complicated. If you read all the pins from 0 to 53 then why not just send to the PC a simple string like this "001110010........." where the first character is the state of pin 0, the second character is the state of pin1 etc

There is no logical value in sending D0, D1 etc as well as the states of the pins.

I'm still not clear what you have in mind with this "I need a funktion in Arduino that will immediately send the current pinstate of the changing ping". (I presume the final word should be "pin")

Can't your PC program easily identify which pin has changed by comparing the new values with the previous values it received? I am a great believer in doing as much of the work as possible on the vastly more powerful PC.

By the way it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Robin2:
To my mind you are making things very complicated. If you read all the pins from 0 to 53 then why not just send to the PC a simple string like this "001110010........." where the first character is the state of pin 0, the second character is the state of pin1 etc

There is no logical value in sending D0, D1 etc as well as the states of the pins.

The reason for D is I need D for the type of pin (Digital or Analog). I know that sending just 0111000... is far better in general.

Robin2:
I'm still not clear what you have in mind with this "I need a funktion in Arduino that will immediately send the current pinstate of the changing ping". (I presume the final word should be "pin")

It means I need some type of auto detection for the a pin. When the pin is high a serial mess is sending to the pc instance in maybe 0.5 sec pf the pin´s state but only for that pin.

Robin2:
Can't your PC program easily identify which pin has changed by comparing the new values with the previous values it received? I am a great believer in doing as much of the work as possible on the vastly more powerful PC.

I am planning for such of comparing function when I have solved the sending problem and auto detection . Maybe this is what I am looking for StateChangeDetection

Robin2:
By the way it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

I will look fo that too :slight_smile:

Fredrik

FredrikH:
The reason for D is I need D for the type of pin (Digital or Analog). I know that sending just 0111000... is far better in general.

Then why not send "01111000...01,1023,1023,1023....."

(I'm assuming you are using analogRead() with the analog pins - but if you are just using digitalRead() they can be part of the group of 0s and 1s.)

It means I need some type of auto detection for the a pin. When the pin is high a serial mess is sending to the pc instance in maybe 0.5 sec pf the pin´s state but only for that pin.

I'm still not clear. Sending all the pin values twice per second would not be onerous and it would completely avoid the need for any special cases.

...R

That id not a bad idea to include the analog pins ex. in the end of 000110001000.... :slight_smile:

Robin2:
"I'm still not clear. Sending all the pin values twice per second would not be onerous and it would completely avoid the need for any special cases."

I am not sure what you are meaning?
I think you say that is would not be a problem to send all the values twice a seconds?

May I ask if you understand Swedish? :slight_smile:

Can you say that I am able to get a reaction in a second for:
Ex: You a switch in ping 2 and a led light on pin 10 when you switch the led-light would light up in second?

Now it takes 2 or 3 seconds for the led to react. Have you did something like that with an Arduino?

FredrikH:
I am not sure what you are meaning?
I think you say that is would not be a problem to send all the values twice a seconds?

Yes

May I ask if you understand Swedish? :slight_smile:

No, but my second son lives near Stockholm

Can you say that I am able to get a reaction in a second for:
Ex: You a switch in ping 2 and a led light on pin 10 when you switch the led-light would light up in second?

Now it takes 2 or 3 seconds for the led to react. Have you did something like that with an Arduino?

I think it is time you described the project you are trying to create instead of just asking questions about how you think small parts of it might be implemented. That is what is known as an XY-Problem. I suspect there is a better and simpler way.

...R

Robin2:
Yes
No, but my second son lives near Stockholm
I think it is time you described the project you are trying to create instead of just asking questions about how you think small parts of it might be implemented. That is what is known as an XY-Problem. I suspect there is a better and simpler way.

...R

I think it too it´s time :slight_smile:

I will reply on that sooner!

I am building a FlightSimulator panel with alot of components total input of 387 pins and output of 133 pin. Some out are leds and are controlled by Phidget. The input are a lot of diff. Switches, Rotary Encorder/Switches, Led-Displays ....

I need make some test seeing if Arduino is the way to go for my project. I have also tried the urb firmata and the lib... SolidSoils. I had problem to make the lib.. working. I was able turn on a led-light according the led-light exampel!

I have no idea what Phidget, urb firmata or SolidSoils are.

Is it your plan to use a PC with a C# program to provide the "intelligence" and use a number of Arduinos to act as an interface between the PC and the switches and LEDs?

If so it may be possible to allocate an Arduino to a group of switches and leds. For example, maybe an LED could be changed by the Arduino in response to a switch movement without the LED "data" needing to go to the PC.

And if the Arduinos are allocated to a group of activities it should mean that that group can be developed in isolation from other groups making debugging easier.

Just my 3 cents ...

...R

I briefly looked at the Phidget website.

Not sure there is a need to mix Arduino with Phiddgets. :roll_eyes:

Hi

Accept from to make a own programming in Arduino or a pc program. I am also considering to use some plug&play program and maybe other board?

I am a Webbdeveloper who looking for a job and my focus must be at the right thing. The times is not enough for all the stuff we like to do. Anyway I like to know if there is a limit in how long the connection cable can be between a component and the board?

FredrikH:
Anyway I like to know if there is a limit in how long the connection cable can be between a component and the board?

What sort of component?

What length would you like to be able to use?

...R

Robin2:
What sort of component?

What length would you like to be able to use?

...R

My components are as follows:
• Switches – on/off | on /off / on | mom/ off/ mom ……..
• Rotary Switches – 12 pos (Pin for each poss)
Rotary Encorder
LED - Displays
LED – Segments
LED-Lights

Tot: 387 inputs and 133 outputs :wink:

Length for the longest cable are 210 cm (2100 mm) :slight_smile:

I will have the all the boards in the same place.

I suspect you will not have a problem with 2 or 3 metres of cable but you will probably need to be careful how you route the wires to minimise the interference they can pick up or cause. It may be wise to use twisted pairs (like in a CAT 5 or CAT 6 cable). Each twisted pair should be signal and GND.

If you are using a few Arduinos I suggest you locate the Arduino so as to minimise the length of cable to components. There should be no problem communicating between the Arduinos at a distance of 1 or 2 metres. This can also greatly reduce the spaghetti of wire.

...R

What type of wires do you to prefer so I can avoid that?

I have this type --> https://www.datacorec.com/index.php?main_page=product_info&products_id=474286

Bought in Ebay 2018!

Solid core wire is a bad idea. It will work harden when it is bent or flexed and that easily leads to breakages. By all means use it for testing and short term projects but for anything long term use multi-strand wire.

I find that a cheap source of wire is to buy a length of CAT 5 or CAT 6 ethernet cable. (CAT 6 has heavier conductors so is better). You can either use it as it comes or strip the outer shielding off and use the twisted pairs separately. And of course you can separate the twisted pairs. Note that you can buy that cable with multi-core or solid conductors and you should get the multi-core type. You can probably buy 2m or 3m lengths with connectors on each end at a price that justifies cutting off the connectors and throwing them in the trash. Or you may find a supplier than sells it by the metre.

The CAT X cable also has the advantage that the wires have different colours.

Separately, the general advice is that crimped connectors on a wire are more reliable than soldered connectors because the hard solder creates a crease point where the wire can break. I bought a box of assorted DuPont connectors on Ebay or Amazon for a very attractive price. These are the same sort of connectors that you see on an Uno. The box I bought includes male and female pins. They can be a little fiddly to crimp with a small pliers but the proper crimping tool is expensive.

...R

Robin2:
Solid core wire is a bad idea. It will work harden when it is bent or flexed and that easily leads to breakages. By all means use it for testing and short term projects but for anything long term use multi-strand wire.

I find that a cheap source of wire is to buy a length of CAT 5 or CAT 6 ethernet cable. (CAT 6 has heavier conductors so is better). You can either use it as it comes or strip the outer shielding off and use the twisted pairs separately. And of course you can separate the twisted pairs. Note that you can buy that cable with multi-core or solid conductors and you should get the multi-core type. You can probably buy 2m or 3m lengths with connectors on each end at a price that justifies cutting off the connectors and throwing them in the trash. Or you may find a supplier than sells it by the metre.

The CAT X cable also has the advantage that the wires have different colours.

Separately, the general advice is that crimped connectors on a wire are more reliable than soldered connectors because the hard solder creates a crease point where the wire can break. I bought a box of assorted DuPont connectors on Ebay or Amazon for a very attractive price. These are the same sort of connectors that you see on an Uno. The box I bought includes male and female pins. They can be a little fiddly to crimp with a small pliers but the proper crimping tool is expensive.

...R

It´s sounds a great solution to use CAT 6 cables for the transport between the board and my components. For start at the board´s side I have This Wirer

Maybe use a Sub connector module or use Quick able connector

In the components sideI will use the cable I was showing, just a fec cm maybe 20-30 cm and then use the quick connector. Let´s see what is the best way?

Then for transport a modify Network cable :slight_smile:

FredrikH:
Hi

I have almost reach to the end of testing Arduino for my project. If you are looking bellow you can see that the outcomming stream from Arduino is is like:
D0-(1-9)=(0/1)
D(10-53)=(0/1)

The Arduino are sending a stream containing all the states for each digital pins, see the code bellow:

My sketch for the Arduino board (loop function):

void setup()

{
  Serial.begin(9600);

// Set pinMode for the board pins ===========================================
.....................
  // ==========================================================================
}

void loop()
{
  // Declaration of containers
  String controlStr, controlStrType, controlStrPinType, controlStrPin, controlStrBool, readString;
 
  // ======================== Save the (input / input_pullupp ) pinstates in an array of lenght = 54 ===============================
    int pinStatesArr[54];
    for (int i = 0; i < pinAmount; i = i + 1){
      if(i == 0 || i == 1) pinStatesArr[0] = -1;
      else pinStatesArr[i] = digitalRead(digitalPinsArr[i]);
    }
 
  // ======================== Write state of the changing pin
// If loopIndex is  bellow 10 add a zero next to 2-53
  if(loopIndex < 10){
    if(pinStatesArr[loopIndex] == 0) Serial.println(String('D')+String('0')+loopIndex+String("=0"));  // Opened = INPUT_PULLUP = 0
    if(pinStatesArr[loopIndex] == 1) Serial.println(String('D')+String('0')+loopIndex+String("=1")); // Closed = INPUT_PULLUP = 1
  }
  if(loopIndex >= 10){
    if(pinStatesArr[loopIndex] == 0) Serial.println(String('D')+loopIndex+String("=0"));  // Pin = Opened = INPUT_PULLUP = 0

if(pinStatesArr[loopIndex] == 1) Serial.println(String('D')+loopIndex+String("=1"));  // Pin =  while(Serial.available()){
    delay(1);
    if(Serial.available()>0){
      char incommingString = Serial.read();
      if(isControl(incommingString)){
        break;
      }
        // Save the string and add the new one
        readString += incommingString;
        // Save the string in more of a global container reacheable further
        controlStr = readString;
    }
  } 
  loopIndex++;
  if (loopIndex == pinAmount) loopIndex = 0;
}




Inside the C# program is a while loop tha will handle the string (serialPort.ReadLine())


My class for "ConnectionArduinoD1" (C# side):


using ....

namespace FSPanel_App___Backend
{
    class ConnectionArduinoD1
    {
        static string type;
        static string pinNr;
        static string  pinState;
        static string[] boardsPinstates = new string[]{
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state",
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state",
            "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state", "state" };
        static bool firstRunOpen = true;
        static bool connect;
        static SerialPort serialPort;
        public static void BoardStart()
        {
            Thread readThread = new Thread(Read);
            serialPort = new SerialPort();
            OpenSerialPort();
            Console.WriteLine($"Connected to port {serialPort.PortName} at {serialPort.BaudRate} baud.");
            readThread.Start();
        }
        public static void Read()
        {
            while (connect)
            {
                try
                {
                    var message = serialPort.ReadLine();
                    Console.WriteLine(message);
                    SplitString(message);
                    if (message == "D2=Open\r") boardsPinstates[2] = "Open";
                    if (message == "D2=Close\r") boardsPinstates[2] = "Close";
                    if (message == "D7=Open\r") boardsPinstates[7] = "Open";
                    if (message == "D7=Close\r") boardsPinstates[7] = "Close";
                   
                    Switch3Poss();
                }
                catch (TimeoutException) { }
                firstRunOpen = false;
               
                //serialPort.WriteLine("");
            }
        }
        private static void SplitString(string messagesSplit)
        {
            type = messagesSplit.Substring(0, 1);
            pinNr = messagesSplit.Substring(1, 2);
            pinState = messagesSplit.Substring(4, 1);
        }
            private static void Switch3Poss()
        {
            /*Control string for Arduinos component commands. There are different typ according the components. It starts = inp/out
                inp:
                    Switch - 2 / 3 poss (Middle poss =

out:

_a/d_01-53_1/0
            */
            if (boardsPinstates[2] == "Open" && boardsPinstates[7] == "Close") {
                serialPort.WriteLine("out_d_10_1");
            }
            if(boardsPinstates[2] == "Close" && boardsPinstates[7] == "Close")
            {
                serialPort.WriteLine("out_d_11_1");   
                firstRunOpen = false; 
            }
            if(boardsPinstates[2] == "Close" && boardsPinstates[7] == "Open")
            {
                serialPort.WriteLine("out_d_10_0");
                serialPort.WriteLine("out_d_11_0");
            }
        }
        private static void OpenSerialPort()
        {
            serialPort.PortName = "Com4";
            serialPort.BaudRate = 9600;
            serialPort.ReadTimeout = 5000;
            serialPort.WriteTimeout = 5000;
            serialPort.Open();
            connect = true;
           
            Console.WriteLine($"Connected to port {serialPort.PortName} at {serialPort.BaudRate} baud.");
        }
    }
}




All works fine but I will add additional behavior. I need a funktion in Arduino that will immediately send the current pinstate of the changing ping. I have search for it and ask in a forum. I was told that I need some sort of "interrupt" function 
--> 
https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt

You have a table next to hte first text subparagraph for "Mega, Mega2560, MegaADK" you can read that this function just work for digitalpins "2, 3, 18, 19, 20, 21". 

It causing a problem since I have about 30 switches for almost every boards.

The question is am I able to find a solutions so I can use Arduino?

Look at the txt file :)

Best regards Fredrik

Here everything about the serial port and Arduino with C #, VB .net and C ++.

https://forum.arduino.cc/?topic=494946#msg3376522

:wink: