problems with serial not working with C# application
sovr610
Posts: 3
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:
and here is the C# code just for the serial port:
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!
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!
Comments
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.
When I get a chance I may try this out and see.
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.
Ray