Serial Communication - LattePanda Leonardo [SOLVED]

A place to talk about all the Operating Systems, Software & Hardware
Forum rules

- Posts are to be made in the relevant forum. Users are asked to read the forum descriptions before posting.

- Members should post in a way which is consistent with "normal writing". That is users should not post excessive numbers of emoticons, large, small or coloured text, etc. Similarly users should not SHOUT or use excessive punctuation (e.g. ! and ?) in topic titles or posts.

- Members should use an appropriate, descriptive subject when posting a new topic. Examples of bad subjects include; "Help me!", "I'm stuck!", "I've got an error!", etc. Examples of good subjects include; "Getting an TABLE FULL error upon login", "Cannot restore a backup".

- Members are asked to post in English only so that posts can be well received and properly monitored.

- Spam is not tolerated here under any circumstance. This includes offering hosting services (charged and free), installation services, solicitation etc. Recruiting members for your own projects (moderators, designers, professional MOD work, etc.) is not permitted and is also considered spam. Users posting spam will be warned and their post removed.

- Members should post in a way that is respectful of other users. Flaming or abusing users in any way will not be tolerated and will lead to a warning. Vulgar language and inappropriate material is not allowed and will be removed. We try to maintain a family friendly atmosphere whenever it is possible within the main subject matter of this community. Please keep this in mind when participating.

- Each user is allowed to create one account. If you would like to change your username, please contact us and, most likely, we can do it for you while you can keep all of your profile data, posts, and other content.

- If a user violates our guidelines and shows a disregard for them, our staff and our community, they run the risk of losing their account. We reserve the right to deactivate any account and to edit or remove any content without warning. These guidelines are subject to change at any time without notice.

Thank you for visiting LattePanda.com!
User avatar
ChicagoBob123
Posts: 37
Joined: Fri May 19, 2017 9:56 pm

Mon Aug 28, 2017 9:44 pm

This is my initialization code in C#
I initialize with two threads read and write.

public AdruinoIO(ApplicationSettings ap)
{
serialPort = new SerialPort(ap.adruinoComPort, 115200, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.None;
serialPort.DtrEnable = true;
Thread readThread = new Thread(Read);
readThread.Name = "Serial ReadThread";
Thread writeThread = new Thread(Write);
writeThread.Name = "Serial WriteThread";

// Allow the user to set the appropriate properties.
// Set the read/write timeouts
serialPort.ReadTimeout = 1000;
serialPort.WriteTimeout = 1000;

serialPort.Open();
readThread.Start(ap);
writeThread.Start(ap);
}

User avatar
atestani
Posts: 19
Joined: Mon Aug 14, 2017 7:27 pm

Tue Aug 29, 2017 3:31 am

I ran the StandardFirmata sketch on the onboard Arduino and the C# LattePandaFirmataDemo and it worked, i.e. I could click the buttons to turn on/off the Arduino LED. This is an example of successfully sending serial data from the LattePanda CPU and the onboard Arduino.

Unfortunately, the Firmata Arduino library is written in C++, uses HardwareSerial.h and Streams, and is generally complex and difficult to understand. It is also *very* slow.

I still do not understand why a simple Arduino sketch with standard functions to send some data to the Arduino via its COM port doesn't work (even from the Serial Monitor)! I would be grateful if someone would share a working sketch that does this.

User avatar
Lutz
Posts: 214
Joined: Mon Apr 18, 2016 4:30 am
Location: Germany, NRW

Tue Aug 29, 2017 7:44 am

google : "arduino firmata c#"
First result : https://github.com/SolidSoils/Arduino

Maybe you will find something useful.

User avatar
atestani
Posts: 19
Joined: Mon Aug 14, 2017 7:27 pm

Sat Sep 02, 2017 3:23 am

Thanks... This looks like it will work as it is another layer on top above Firmata.

However, I am looking for an answer why simple and straight forward C# and Arduino code as I originally posted doesn't work to send serial strings. Strings sent from the Arduino to the LattePanda CPU work fine as does a separate/external Arduino (Mega 2560) which also works fine with the same code.

There is something wrong (or strange) with the LattePanda in this regard.

User avatar
Lutz
Posts: 214
Joined: Mon Apr 18, 2016 4:30 am
Location: Germany, NRW

Sat Sep 02, 2017 7:32 am

Arduino Leonardo :
Basics : https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro
Differences to other Arduino : https://www.arduino.cc/en/Guide/Arduino ... icro#toc11


Arduino Mega :
Basics : https://www.arduino.cc/en/Guide/ArduinoMega2560

... and VERY IMPORTANT (Sorry, I forgot) :
Update your Arduino IDE to newest version. This includes also USB driver you need for communication.
https://www.arduino.cc/en/Main/Software

User avatar
atestani
Posts: 19
Joined: Mon Aug 14, 2017 7:27 pm

Sun Sep 03, 2017 1:31 pm

Thanks, Lutz. That's very useful information.

I believe I made provision for the serial port differences in the code I posted at the start of this thread. As I have said, I can send data from the Leonardo to the LattePanda CPU so the serial port is enumerated. My problem is sending data to the Leonardo from the LattePanda CPU

Also, I did upgrade the Arduino software to v1.69 before I started this. I believe the changes for Leonardo were put in v1.67. I see there was also a change to allow SerialUSB as an alias for Serial. I will try upgrading to a later level of Arduino and using SerialUSB.

User avatar
atestani
Posts: 19
Joined: Mon Aug 14, 2017 7:27 pm

Mon Sep 04, 2017 1:59 am

OK... I tried the latest Arduino version (1.84) including the USB driver with the same results: cannot send data from LattePanda CPU to on board Leonardo. Sending from Leonardo to LattePanda works fine.

Has anyone been able to make this work?!

Here is the Arduino test code:

Code: Select all

//******* MACROS *******
#define  set(xpin) (digitalWrite(xpin, HIGH))  
#define  clr(xpin) (digitalWrite(xpin, LOW)) 
#define  Get(xpin) (digitalRead(xpin))

//******* GLOBAL VARIABLES *******
String inputString;
boolean stringComplete = false;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long interval = 10000;

//******* PIN DEFINITIONS *******
int LED = 13;

//-----------------------------------------------
void flashLED(int t)
//-----------------------------------------------
{
	set(LED);
	delay(t);
	clr(LED);
}

//-----------------------------------------------
void serialEvent()
//-----------------------------------------------
{
	while (SerialUSB.available())
	{
		char inChar = (char)SerialUSB.read();
		if (inChar == '\n')
		{
			stringComplete = true;
			return;
		}
		inputString += inChar;
	}
}

//-----------------------------------------------
void setup()
//-----------------------------------------------
{
	int i;

	pinMode(LED, OUTPUT);
	SerialUSB.begin(115200);

while (!SerialUSB)
	{
	set(LED);
	delay(50);
	clr(LED);
	delay(50);
}

	inputString.reserve(64);
	inputString = "";

for (i = 0; i < 5; i++)
	{
		set(LED);
		delay(250);
		clr(LED);
		delay(250);
	}
//delay(2000);
SerialUSB.println("Setup comnplete...");
}

//-----------------------------------------------
void loop()
//-----------------------------------------------
{
	currentMillis = millis();

	if((currentMillis - previousMillis) > interval)
	{
		SerialUSB.println("Ready...");
		previousMillis = currentMillis;
		flashLED(50);
	}
	if (stringComplete) 
	{
		SerialUSB.print("Echo: |" + inputString + "|\n");
		inputString = "";
		stringComplete = false;
		flashLED(10);
	}
}



User avatar
Lutz
Posts: 214
Joined: Mon Apr 18, 2016 4:30 am
Location: Germany, NRW

Mon Sep 04, 2017 4:45 am

I really have to say sorry, but I am out of ideas now... :oops:

User avatar
Lutz
Posts: 214
Joined: Mon Apr 18, 2016 4:30 am
Location: Germany, NRW

Wed Sep 06, 2017 9:42 am

I found something interesting "foreach..." inside a "non Arduino" Project, maybe it helps :

Code: Select all

    public partial class Window_Serial : Window
    {


        //Serial 
        SerialPort serial = new SerialPort();

        // Timer
        DispatcherTimer TimeoutTimer = new DispatcherTimer();



        #region Properties

        private static bool _CRrecieved;
        public static bool CRrecieved
        {
            get
            {
                return _CRrecieved;
                //throw new System.NotImplementedException();
            }

            set
            {
                _CRrecieved = CRrecieved;
                //throw new System.NotImplementedException();
            }
        }


        private static string _RecievedString;
        public static string RecievedString
        {
            get
            {
                return _RecievedString;
                //throw new System.NotImplementedException();
            }

            set
            {
                _RecievedString = RecievedString;
                //throw new System.NotImplementedException();
            }
        }

        #endregion



        public void Init()
        {

            textBox_Terminal.Text = "";


            if (serial.IsOpen)
            {
                serial.Close();
            }
            else
            {
                //Sets up serial port
            }

            //serial.PortName = "COM1"; //Comm_Port_Names.Text;
            serial.PortName = Properties.Settings.Default.COM_Port__S4; // COM1

            serial.BaudRate = Convert.ToInt32(9600);
            serial.Handshake = System.IO.Ports.Handshake.None;
            serial.Parity = Parity.None;
            serial.DataBits = 8;
            serial.StopBits = StopBits.One;
            serial.ReadTimeout = 200;
            serial.WriteTimeout = 50;

            //serial.ReadBufferSize = 1;
            serial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

            // A time period expressed in 100-nanosecond units. 
            // TimeSpan.TicksPerMillisecond;
            TimeSpan TimeOut = new TimeSpan(1000 * TimeSpan.TicksPerMillisecond);  // sollten 1000ms sein...      
            TimeoutTimer.Tick += new EventHandler(TimeoutTimer_Tick);
            TimeoutTimer.Interval = TimeOut;

            
            serial.Open();

        }



        #region Sending        

        public void SendString(string data)
        {
            if (serial.IsOpen)
            {
                _RecievedString = "";
                _CRrecieved = false;

                textBox_Terminal.AppendText("<= : " + data);

                try
                {
                    // Send the binary data out the port
                    byte[] hexstring = Encoding.ASCII.GetBytes(data);
                    //There is a intermitant problem that I came across
                    //If I write more than one byte in succesion without a 
                    //delay the PIC i'm communicating with will Crash
                    //I expect this id due to PC timing issues ad they are
                    //not directley connected to the COM port the solution
                    //Is a ver small 1 millisecound delay between chracters
                    foreach (byte hexval in hexstring)
                    {
                        byte[] _hexval = new byte[] { hexval }; // need to convert byte to byte[] to write
                        serial.Write(_hexval, 0, 1);
                        //Thread.Sleep(1);
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
            }
            else
            {
            }
        }


        #endregion



        #region Recieving

        // ???
        //private delegate void UpdateUiTextDelegate(string text);  
        private void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();

            if (_CRrecieved == false)
            {
                _RecievedString = _RecievedString + indata;

                if (_RecievedString.Contains("\r"))
                {
                    _CRrecieved = true;
                    TimeoutTimer.Stop();

                }
                else
                {
                    _CRrecieved = false;
                }

            }
        }

        private void WriteData(string text)
        {

            this.textBox_Terminal.AppendText(">> :-|" + text + "|-[CRLF]\r\n");

        }

        #endregion



        #region ControlEvents

        public Window_Serial()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void textBox_Terminal_TextChanged(object sender, TextChangedEventArgs e)
        {
            if(textBox_Terminal.LineCount > 25 )
            {
                string starttext = "";
                string helptext = "";
                int startindex = 0;


                starttext = textBox_Terminal.Text;

                startindex = starttext.IndexOf("\r") + 1;

                helptext = starttext.Substring(startindex, 1);
                if( helptext == "\n")
                {
                    startindex++;
                }
                helptext = starttext.Substring(startindex);

                textBox_Terminal.Text = helptext;

            }
        }


        private void TimeoutTimer_Tick(object sender, EventArgs e)
        {

            _RecievedString = ("Timeout\r");
            _CRrecieved = true;

        }

        #endregion

        }
    }

User avatar
atestani
Posts: 19
Joined: Mon Aug 14, 2017 7:27 pm

Thu Sep 07, 2017 12:13 pm

So, I am running the same code on an external Leonardo and am having the same issue. The root of the issue is that Leonardo and a couple of other Arduino models don't use a separate processor or FTDI chips to implement the primary serial port. It is a virtual serial port (USB-CDC) that is switched between uploading code to the SerialUSB (or Serial) port. This was done to lower the cost.

There are countless posts about this "difference" in the Leonardo and I am still trying to find the answer on how to send serial data to the Leonardo. Sending from Leonardo continues to work. One thing I have learned is that SerialUSB does NOT fire SerialEvent but I have pur the code in loop() and it still doesn't work.

If anyone has an answer on how to use the serial port on Leonardo I would be grateful for the information.

I have to stop working on this to focus on preparation for hurricane Irma who is bearing down on us in So. Florida.

Post Reply