Shop OBEX P1 Docs P2 Docs Learn Events
problems with serial not working with C# application — Parallax Forums

problems with serial not working with C# application

sovr610sovr610 Posts: 3
edited 2014-07-14 08:37 in Propeller 1
Hello everyone, I am new to the forums! I have been working with the propeller for around 6 years and I have been getting back into it. I wrote an old C# application that worked just fine over the serial port, but I just copied and pasted it to a new visual studio 2012 project along with a fresh new piece of spin code using the fullDuplexSerial. I have it working where the propeller chip can send data to the C# application, but I seem to not be able to send data to the propeller chip correctly. I see the blue light blink when I send data to the propeller chip, but when I send an "a" I don't get an "a" on the propeller... I must be missing a step, but I think the problem is on the propeller side. Here is the spin code:
OBJ


        serial : "FullDuplexSerial"
        serials : "FullDuplexSerial"
var
        byte rec
PUB Main | iobyte
        'both pins 0 and 1 are connected to LED's
        dira[0]~~  'used to see if the C# app gives an "a"
        dira[1]~~  'used to see if the code is looping
        serials.start(31, 30, 0, 115200)


        repeat
          waitcnt(cnt+1_000_000)
          outa[1]~
          serials.str(string("hey"))
          waitcnt(cnt+1_000_000)
          outa[1]~~
          rec := serials.rxtime(10)
          if rec == "a" and rec <> -1
             outa[0]~~

and here is the C# code just for the serial port:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using PAD_SCRIPT;




namespace PAD_CORE_ENGINE
{
    public struct serialNumbers
    {
        public double temperature_internal;
        public double temperature_external;


        public double encoder_1_count;
        public double encoder_2_count;
        public double encoder_3_count;
        public double encoder_4_count;
        public double encoder_5_count;
        public double encoder_6_count;


        public double sensor_1;
        public double sensor_2;
        public double sensor_3;
        public double sensor_4;
        public double sensor_5;
        public double sensor_6;


        public double var_1;
        public double var_2;
        public double var_3;
        public double var_4;
        public double var_5;
        public double var_6;




        
    }




    class Serial_Port
    {
        private SerialPort port = new SerialPort();
        private static string indata = null;
        private Log log;
        private static serialNumbers nums;
        /// <summary>
        /// constructor for setting a custom serial_port
        /// </summary>
        /// <param name="BaudRate"></param>
        /// <param name="par"></param>
        /// <param name="bits"></param>
        /// <param name="Databits"></param>
        /// <param name="hand"></param>
        /// <param name="name"></param>
        public Serial_Port(int BaudRate, Parity par, StopBits bits, int Databits, Handshake hand, string name)
        {
            log = new Log();
            port.BaudRate = BaudRate;
            port.Parity = par;
            port.StopBits =
                bits;
            port.DataBits = Databits;
            port.Handshake = hand;


            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            try
            {
                port.Open();
            }
            catch (Exception i)
            {
                Console.WriteLine(i.ToString());
            }
            serialPorts = new string[20];
        }


        /// <summary>
        /// custom serial_port that is easier to setup
        /// </summary>
        /// <param name="name">name, like COM3</param>
        public Serial_Port()
        {
            log = new Log();
            serialPorts = new string[20];
        }




        public void setupPort(string name)
        {
            port.BaudRate = 9600;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;
            port.DataBits = 8;
            port.ReadTimeout = 1000;
            port.PortName = name;


            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);


            try
            {
                port.Open();
            }
            catch (Exception i)
            {
                Console.WriteLine(i.Message);
                log.sayError(i.Message);
            }
        }


        /// <summary>
        /// open the serial port for gatting and sending info
        /// </summary>
        public void openPort()
        {
            try
            {
                port.Open();
            }
            catch (Exception i)
            {
                Console.WriteLine(i.Message);
                log.sayError(i.Message);
            }
        }




        /// <summary>
        /// close serial port when done
        /// </summary>
        public void ClosePort()
        {
            try
            {
                port.Close();
            }
            catch (Exception i)
            {
                Console.WriteLine(i.Message);
                log.sayError(i.Message);
            }
        }


        /// <summary>
        /// get the object of the serial port
        /// </summary>
        /// <returns>the serial port object</returns>
        public SerialPort getPort()
        {
            return port;
        }


        /// <summary>
        /// the event handler for getting info from serial port
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">arg with info</param>
        private static void DataReceivedHandler(
                    object sender,
                    SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            try
            {
                indata = sp.ReadExisting();
                setInternalSystem(indata, "&");


            }
            catch (Exception i)
            {
                Console.WriteLine(i.Message);
            }


        }


        /// <summary>
        /// get the data from the serial port
        /// </summary>
        /// <returns>the port data as a string</returns>
        public string getDataPort()
        {
            return indata;
        }


        /// <summary>
        /// set the serial port name like COM3
        /// </summary>
        /// <param name="name">string of port name</param>
        public void setSerialPortName(string name)
        {
            port.PortName = name;
        }


        /// <summary>
        /// send data to device through serial port
        /// </summary>
        /// <param name="info">info as string</param>
        public void sendDataPort(string info)
        {
            try
            {
                port.Write(info);
            }
            catch (Exception i)
            {
                Console.WriteLine(i.Message);
                log.sayError(i.Message);
            }
        }


        /// <summary>
        /// display some help for people who don't know serial port commands
        /// </summary>
        public void portHelp()
        {
            Console.WriteLine("setSerialPortName(string name): void");
            Console.WriteLine("sendDataPort(string info): void");
            Console.WriteLine("findPort(): void");
            Console.WriteLine("getNameOfserialPorts(): string");
            Console.WriteLine("getDataPort(): void");
        }


        private string[] serialPorts;


        /// <summary>
        /// collect all of the serial ports that are used or active on your computer
        /// </summary>
        /// <returns>list of port names as an array of strings</returns>
        public string[] findPort()
        {
            serialPorts = System.IO.Ports.SerialPort.GetPortNames();
            return serialPorts;
        }


        /// <summary>
        /// get a single name of serial port based on index number given
        /// </summary>
        /// <param name="index">index number of ports</param>
        /// <returns>port name like COM3</returns>
        public string getNameOfserialPorts(int index)
        {
            if (index <= serialPorts.Length)
            {
                try
                {
                    return serialPorts[index];
                }
                catch (Exception i)
                {
                    Console.WriteLine(i.Message);
                    log.sayError(i.Message);
                }
            }
            return null;
        }






    }
}




I took out some methods that do not conflict with the serial port code. If anyone can help me figure this out that would be great! :smile:

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2014-07-13 14:47
    Your SPIN code is missing the crystal setup. Without it the Propeller defaults to RCFAST which is not good enough for 115200 baud.
  • sovr610sovr610 Posts: 3
    edited 2014-07-13 18:50
    kuroneko wrote: »
    Your SPIN code is missing the crystal setup. Without it the Propeller defaults to RCFAST which is not good enough for 115200 baud.

    what if I put the baud to 9600? will that work or would I still need the crystal setup?
  • jazzedjazzed Posts: 11,803
    edited 2014-07-13 19:46
    sovr610 wrote: »
    what if I put the baud to 9600? will that work or would I still need the crystal setup?


    The problem is that the RCFAST clock is not accurate across chips. But is it precise enough?

    It is possible to find the correct frequency and save it in the CLKFREQ location though. Others here have done such code ... maybe they will see this.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-07-13 19:53
    I have never thought about how stable the RC circuitry is over time/temp.
    When I get a chance I may try this out and see.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2014-07-13 23:13
    In general, most internal RC clocking may vary up to 7% and serial i/o requires something at least less than %3 variation. So it would be a lot simpler to attach a 5MHz crystal than expect the RC clocking to behave within bounds.

    There are a few microcontrollers that have provide internal clocks that are stable enough for asynchronous serial, but not the Propeller.

    This isn't a software problem. It is the actual physical design of the microcontroller.

    You may be able to lock onto a frequency for awhile, but eventually it will drift out of spec.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-07-14 04:16
    I remember back a very long time ago, when I was working with the Propeller on a breadboard, I experimented with a setup without a crystal, the best BAUD rate too work with, or at least the fastest, was 57600. In your Spin program, from the code above, you are using a setup of 115200, In your C# program you are using a default of 9600 on COM3, that looks like a problem. So, change C# code to 57600 and the Spin code to 57600, and see if you get better results.

    Ray
  • sovr610sovr610 Posts: 3
    edited 2014-07-14 08:37
    ok I did some trial and error and putting the crystal in the circuit along with using the 57600 Baud made it work! thank you everyone for your help!
Sign In or Register to comment.