I am new to netduino so I have a simple question (or, it should be simple).
What I want to do is to send an integer (string) via rs232 from my winform app to my netduino plus 2, and then, my netduino should read that integer and blink an onboard led that many times.
I have read online tutorial on that topic and found some examples that should provide communication between my PC and Netduino.
Yes, I did got an echo from it. I am getting an echo even if I disconnect my netduino and hide it in my pocket :).
So much for my understanding of that gadget.
How can I send an info to my Netduino via rs232 cabel that he can read, understand and act accordingly?
There is a code straight from the the web:
For NETDUINO:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO.Ports;
namespace NetduinoApplication1
{
public class Program
{
static SerialPort serial;
public static void Main()
{
// initialize the serial port for COM1 (using D0 & D1)
serial = new SerialPort(SerialPorts.COM1, 9600, Parity.None, 8, StopBits.One);
// open the serial-port, so we can send & receive data
serial.Open();
// add an event-handler for handling incoming data
serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
for (int i = 0; i < 3; i++)
{
led.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
// wait forever...
Thread.Sleep(Timeout.Infinite);
}
static void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// create a single byte array
byte[] bytes = new byte[1];
// as long as there is data waiting to be read
while (serial.BytesToRead > 0)
{
// read a single byte
serial.Read(bytes, 0, bytes.Length);
// send the same byte back
serial.Write(bytes, 0, bytes.Length);
OutputPort led1 = new OutputPort(Pins.ONBOARD_LED, false);
led1.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led1.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
}
}
}
And the code for my console:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace ConsoleRSS
{
class Program
{
static SerialPort serial;
static void Main(string[] args)
{
// provide some usage information
System.Console.WriteLine("enter some text and hit ENTER.");
System.Console.WriteLine("enter 'x' and hit ENTER to exit.");
System.Console.WriteLine();
// initialize the serial port for COM3 (could be other port, depends on system)
serial = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
// open the serial-port, so we can send & receive data
serial.Open();
// add an event-handler for handling incoming data
serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);
// this will hold each line entered
string line = string.Empty;
// as long as an x is not entered
while (line.ToLowerInvariant() != "x")
{
// read a single line from the console
line = System.Console.ReadLine();
// convert the line to bytes
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(line);
// send the bytes over the serial-port
serial.Write(utf8Bytes, 0, utf8Bytes.Length);
}
}
static void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// wait a little for the buffer to fill
System.Threading.Thread.Sleep(100);
// create an array for the incoming bytes
byte[] bytes = new byte[serial.BytesToRead];
// read the bytes
serial.Read(bytes, 0, bytes.Length);
// convert the bytes into a string
string line = System.Text.Encoding.UTF8.GetString(bytes);
// write the received bytes, as a string, to the console
System.Console.WriteLine("echo: " + line);
System.Console.WriteLine();
}
}
}
I'm not sure what problem you are actually getting with this? Your code at first glance looks correct.
I would try checking your hardware first, so is the usb cable actually set as COM 1 in device manager on your pc? Is the cable connected to the correct ports in the netduino?
Related
How can I send a hexadecimal like 0x2b or 0x42 to a serial port using either C# or Php.
42 is the HEX that I need to send by the way.
I used this for C#
using System.IO.Ports;
namespace Card_Reader
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8))
{
byte[] bytesToSend = new byte[1] { 0x2A };
port.Open();
port.Write(bytesToSend, 0, 1);
}
}
but nothing happens to the device connected to my serial port.
Now I used this for Php
public function dispense_card() {
$serial = new CI_Phpserial();
// First we must specify the device. This works on both linux and windows (if
// your linux serial device is /dev/ttyS0 for COM1, etc)
$serial->deviceSet("COM2");
// We can change the baud rate, parity, length, stop bits, flow control
$serial->confBaudRate(9600);
$serial->confParity("even");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");
// Then we need to open it
$serial->deviceOpen();
// To write into
/*$serial->sendMessage(0x42);*/
$str = pack("h*",66);
$serial->sendMessage($str);
}
I'm getting close to hanging myself since I'm trying to do this since last year and until now I cannot accomplish it.
Newbie here when it comes to serial data sending.
When i read the serial port using c# in a console application, this is the output i get.
Does anyone know how i should read this data so it's readable by a human.
The data that should be received is like : 6025 1045 1806 116 0000000 and GPS coördinates.
I know its a bit vague, but i am new to serial port programming and would like to know how to move on.This is the code i have so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace ClarityListener
{
class Program
{
static void Main(string[] args)
{
ClarityWarning("Starting communication...");
SerialPort Dave = new SerialPort("COM1");
Dave.BaudRate = 9600;
Dave.Parity = Parity.Odd;
Dave.DataBits = 8;
Dave.StopBits = StopBits.One;
Dave.Handshake = Handshake.None;
Dave.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
try
{
Dave.Open();
ClarityMssg("Connected!\n");
}
catch
{
ClarityError("Problem!\n");
}
ClarityWarning("Press any key to shutdown program");
Console.WriteLine();
Console.ReadKey();
Dave.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
ClarityWarning("Data received : ");
ClarityWarning(indata.ToString() + "\n");
}
private static void ClarityMssg(string message)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.White;
}
private static void ClarityError(string message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.White;
}
private static void ClarityWarning(string message)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.White;
}
}
}
Data received over a channel is a stream of bytes, being it over tcp/ip or serial or read from a file. Programming against a serial port is not that different/difficult as there is no hitech black magic involved.
Just dumping the received bytes to the console assuming that it is ascii is not the way to go. Although it can give you a head-start in determining what's send.
First check the parameters set on the receiving serial-port. Most devices are using 9600 baud, no parity, 8, 1 stopbit. If there is a mismatch data gets mangled. Check the specs from the manual of the device.
Do you know in what format the data is send? Are numbers converted to ascii literals before sending or are they send as int32 in 4 bytes?
What is the flow control of the source?
Are there control/command bytes in or between the messages?
In short: know the protocol used by the sender. Check the documentation and as a last resort call the vendor / distributor.
First things that come to mind :
make sure the parity, stop bits and baud rate of your serial port reader are configured to match the requirements of the device sending the data.
Also make sure your serial device is indeed sending ASCII encoded text.
(this is the standard for NMEA, a protocol mostly used for devices like this, but there is no guarantee your device adheres the the standard 100%)
Not a whole lot to say here other than this doesn't work, and I have no idea why.
The serial output on the Arduino is nothing. The output on the C# code goes down to waiting for a response and then nothing.
The Bluetooth card LED on the Arduino goes green when I start the C# program so there is a connection being made. Just nothing else.
Arduino Code
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 8 // This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7 // This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)
SoftwareSerial blueToothSerial(RxD,TxD);
boolean light = false;
void setup(){
Serial.begin(9600); // Allow Serial communication via USB cable to computer (if required)
pinMode(RxD, INPUT); // Setup the Arduino to receive INPUT from the bluetooth shield on Digital Pin 6
pinMode(TxD, OUTPUT); // Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
pinMode(13,OUTPUT); // Use onboard LED if required.
}
void loop(){
delay(1000);
if(light){
light = false;
digitalWrite(13,LOW);
}
else{
light = true;
digitalWrite(13,HIGH);
}
//Serial.println(blueToothSerial.available());
blueToothSerial.write("Im alive");
if(blueToothSerial.read()>0){
Serial.write(blueToothSerial.read());
}
}
Core C# Code
static void Main(string[] args)
{
byte[] Command = Encoding.ASCII.GetBytes("It works");//{0x00,0x01,0x88};
SerialPort BlueToothConnection = new SerialPort();
BlueToothConnection.BaudRate = (9600);
BlueToothConnection.PortName = "COM4";
BlueToothConnection.Open();
if (BlueToothConnection.IsOpen)
{
BlueToothConnection.ErrorReceived += new SerialErrorReceivedEventHandler(BlueToothConnection_ErrorReceived);
// Declare a 2 bytes vector to store the message length header
Byte[] MessageLength = { 0x00, 0x00 };
//set the LSB to the length of the message
MessageLength[0] = (byte)Command.Length;
//send the 2 bytes header
BlueToothConnection.Write(MessageLength, 0, MessageLength.Length);
// send the message itself
System.Threading.Thread.Sleep(2000);
BlueToothConnection.Write(Command, 0, Command.Length);
Messages(5, ""); //This is the last thing that prints before it just waits for response.
int length = BlueToothConnection.ReadByte();
Messages(6, "");
// retrieve the reply data
for (int i = 0; i < length; i++)
{
Messages(7, (BlueToothConnection.ReadByte().ToString()));
}
}
}
Okay so there were a few issues that are hard to see from above so I will attempt to explain.
First, RX and TX on the bluetooth card DO NOT go to their equals on the arduino. They go to their opposites.
Example:
Bluetooth Card RX -> TX on Arduino
Bluetooth Card TX -> RX on Arduino
So if you look in the photo of the Arduino above it should be painfully obvious that pins 7 and 8 are the incorrect placement.
The next issue that I was having was poor connectivity.
The power and ground seem to be fine in the above configuration. However, the RX and TX connections need to be soldered in. Otherwise you get a poor connection.
Once I made this changes the above code worked flawlessly.
Hope this helps anyone else having these issues!!
Here is similar code simplified for testing the PC <-> Arduino BT communication. In the code below, the PC sends text to the Arduino, which then echoes it back to the PC. PC writes the incoming text to console.
Set your BT serial port (COM5 in the example) from Windows.
Tested with Arduino Uno, an USB-Bluetooth dongle and the bluetooth module HC-05. Arduino's PIN1(TX) voltage was divided from 5V to 2.5V before feeding it to the module's RX pin).
That's it. Easy!
Arduino:
void setup() {
Serial.begin(9600);
delay(50);
}
void loop() {
if (Serial.available())
Serial.write(Serial.read()); // echo everything
}
C#:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
public class SerialTest
{
public static void Main()
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 9600;
serialPort.PortName = "COM5"; // Set in Windows
serialPort.Open();
int counter = 0;
while (serialPort.IsOpen)
{
// WRITE THE INCOMING BUFFER TO CONSOLE
while (serialPort.BytesToRead > 0)
{
Console.Write(Convert.ToChar(serialPort.ReadChar()));
}
// SEND
serialPort.WriteLine("PC counter: " + (counter++));
Thread.Sleep(500);
}
}
}
Hi to all i am new here and i have heard a lot about this website that it really helps you out. Hope you will be able to help me out!.
I have a very simple program which its only aim is to read from a serial port and prints it on the console window in C# for 2000 times.
I am just turning a variable resistor on a micro-controller that's all
Here below is the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace Testing_serial_v3._0
{
class Program
{
static void Main(string[] args)
{
string buff;
SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
port.Open();
for (int i = 0; i < 2000; i++)
{
buff = port.ReadLine();
Console.WriteLine(buff);
//Console.ReadLine();
}
}
}
}
But there is a funny thing happening in this code. When the console readline is commented as shown in the code above the value from the port changes as i turn the knob of the variable resistor. So this means it is working good.
On the other hand if i make the readline happen so that after each value i have to press a key the port reads the current value and even though i change the knob and press enter again the value will remain the first as if it is not resetting at all?
Do you have to include any other command lines so that the port will reset?
Hope you understand my problem and any other questions you need to know please don't hesitate i really need this problem fixed ASAP.
Many thanks and regards
The data coming through the port is a stream - when you read, you are gradually consuming the stream. You are not seeing "the most recent value", you are seeing "the next value in the stream". When you add the read-line, you add a delay which means there is a large backlog of data. It isn't that "it stayed the same"... Simply that you haven't read to the end (and the more recent values) yet.
In many cases, it would be preferable to deal with the network IO via an async callback so that reading values from the stream is not tied into delays like human data entry. That may involve some knowledge of threading, though.
You could also use a Task to read it in a separate thread and observe it there, kind of what #Marc Gravel mentions. You just have to wait until the task is finished or press enter to cancel it manually. Just another example of offloading the task to another thread.
Here's an example:
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ReadStreamAsyncTask
{
internal class Program
{
private static CancellationToken _cancelTaskSignal;
private static byte[] _serialPortBytes;
private static MemoryStream _streamOfBytesFromPort;
private static CancellationTokenSource _cancelTaskSignalSource;
private static void Main()
{
_serialPortBytes = Encoding.ASCII.GetBytes("Mimic a bunch of bytes from the serial port");
_streamOfBytesFromPort = new MemoryStream(_serialPortBytes);
_streamOfBytesFromPort.Position = 0;
_cancelTaskSignalSource = new CancellationTokenSource();
_cancelTaskSignal = _cancelTaskSignalSource.Token; // Used to request cancel the task if needed.
var readFromSerialPort = Task.Factory.StartNew(ReadStream, _cancelTaskSignal);
readFromSerialPort.Wait(3000); // wait until task is complete(or errors) OR 3 seconds
Console.WriteLine("Press enter to cancel the task");
_cancelTaskSignalSource.Cancel();
Console.ReadLine();
}
private static void ReadStream()
{
// start your loop here to read from the port and print to console
Console.WriteLine("Port read task started");
int bytesToReadCount = Buffer.ByteLength(_serialPortBytes);
var localBuffer = new byte[bytesToReadCount];
int bytesRead = 0;
bool finishedReading = false;
try
{
while (!finishedReading)
{
_cancelTaskSignal.ThrowIfCancellationRequested();
bytesRead += _streamOfBytesFromPort.Read(localBuffer, 0, bytesToReadCount);
finishedReading = (bytesRead - bytesToReadCount == 0);
}
}
catch (TaskCanceledException)
{
Console.WriteLine("You cancelled the task");
}
Console.WriteLine(Encoding.ASCII.GetString(localBuffer));
Console.WriteLine("Done reading stream");
}
}
}
You are sending thousands of data from micro-controller to the serial port (with delay of 1ms for ex.), which makes the buffer of the serial port filled with same values! If you read it one by one by pressing enter key, you are reading the first received ones...
I think if you want to read your data in computer by "Enter" key, you should send the date from micro-controller by a push button! It means you set the value by resistor, press the push button, the micro sends "One Byte" to the computer. You press the enter on the computer and let your computer read just "One Byte" from the serial port!
Also some modification to your code:
static void Main(string[] args)
{
int buff; // string to int
SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
port.Open();
for (int i = 0; i < 2000; i++)
{
Console.ReadLine(); // wait for the Enter key
buff = port.ReadByte(); // read a byte
Console.WriteLine(buff);
}
}
I hope this will work for you! :)
I'm trying to write a small application that simply reads data from a socket, extracts some information (two integers) from the data and sends the extracted information off on a serial port.
The idea is that it should start and just keep going. In short, it works, but not for long. After a consistently short period I start to receive IOExceptions and socket receive buffer is swamped.
The thread framework has been taken from the MSDN serial port example.
The delay in send(), readThread.Join(), is an effort to delay read() in order to allow serial port interrupt processing a chance to occur, but I think I've misinterpreted the join function. I either need to sync the processes more effectively or throw some data away as it comes in off the socket, which would be fine. The integer data is controlling a pan tilt unit and I'm sure four times a second would be acceptable, but not sure on how to best acheive either, any ideas would be greatly appreciated, cheers.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static bool _continue;
static SerialPort _serialPort;
static Thread readThread;
static Thread sendThread;
static String sendString;
static Socket s;
static int byteCount;
static Byte[] bytesReceived;
// synchronise send and receive threads
static bool dataReceived;
const int FIONREAD = 0x4004667F;
static void Main(string[] args)
{
dataReceived = false;
readThread = new Thread(Read);
sendThread = new Thread(Send);
bytesReceived = new Byte[16384];
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort("COM4", 38400, Parity.None, 8, StopBits.One);
// Set the read/write timeouts
_serialPort.WriteTimeout = 500;
_serialPort.Open();
string moveMode = "CV ";
_serialPort.WriteLine(moveMode);
s = null;
IPHostEntry hostEntry = Dns.GetHostEntry("localhost");
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 10001);
Socket tempSocket =
new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
s = tempSocket;
s.ReceiveBufferSize = 16384;
break;
}
else
{
continue;
}
}
readThread.Start();
sendThread.Start();
while (_continue)
{
Thread.Sleep(10);
;// Console.WriteLine("main...");
}
readThread.Join();
_serialPort.Close();
s.Close();
}
public static void Read()
{
while (_continue)
{
try
{
//Console.WriteLine("Read");
if (!dataReceived)
{
byte[] outValue = BitConverter.GetBytes(0);
// Check how many bytes have been received.
s.IOControl(FIONREAD, null, outValue);
uint bytesAvailable = BitConverter.ToUInt32(outValue, 0);
if (bytesAvailable > 0)
{
Console.WriteLine("Read thread..." + bytesAvailable);
byteCount = s.Receive(bytesReceived);
string str = Encoding.ASCII.GetString(bytesReceived);
//str = Encoding::UTF8->GetString( bytesReceived );
string[] split = str.Split(new Char[] { '\t', '\r', '\n' });
string filteredX = (split.GetValue(7)).ToString();
string filteredY = (split.GetValue(8)).ToString();
string[] AzSplit = filteredX.Split(new Char[] { '.' });
filteredX = (AzSplit.GetValue(0)).ToString();
string[] ElSplit = filteredY.Split(new Char[] { '.' });
filteredY = (ElSplit.GetValue(0)).ToString();
// scale values
int x = (int)(Convert.ToInt32(filteredX) * 1.9);
string scaledAz = x.ToString();
int y = (int)(Convert.ToInt32(filteredY) * 1.9);
string scaledEl = y.ToString();
String moveAz = "PS" + scaledAz + " ";
String moveEl = "TS" + scaledEl + " ";
sendString = moveAz + moveEl;
dataReceived = true;
}
}
}
catch (TimeoutException) {Console.WriteLine("timeout exception");}
catch (NullReferenceException) {Console.WriteLine("Read NULL reference exception");}
}
}
public static void Send()
{
while (_continue)
{
try
{
if (dataReceived)
{
// sleep Read() thread to allow serial port interrupt processing
readThread.Join(100);
// send command to PTU
dataReceived = false;
Console.WriteLine(sendString);
_serialPort.WriteLine(sendString);
}
}
catch (TimeoutException) { Console.WriteLine("Timeout exception"); }
catch (IOException) { Console.WriteLine("IOException exception"); }
catch (NullReferenceException) { Console.WriteLine("Send NULL reference exception"); }
}
}
}
}
UPDATE:
Thanks for the response Jon.
What I'm attempting to do is poll a socket for data, if its there process it and send it to the serial port, else keep polling the socket , repeating this whole process ad nauseum.
My initial attempt used a single thread and I was getting the same problem, which led me to believe that I need to give the serial port some more time to allow it to send the data before giving it more data on the next loop, because once I've sent data to the serial port I'm back polling the socket very hard. Having said that IOExceptions occur after approximately 30 seconds of operation, possibly with what I'm saying is I should see IOExceptions immediately?
My interpretation of the join function, I think, is incorrect, ideally calling readThread.Join from send() would allow read() to sleep while still pumping the COM port, but where I have it seems to put the send() to sleep, which I guess is the calling function?? and not producing the desired result.
I've encountered this problem recently as well (and a lot of others have too) - and it's basically a problem with Microsoft's serial port initialization code. I've written a very detailed explanation here if you wish to find out more. I've also suggested a workaround. Hopefully there's enough fuss about this issue such that Microsoft would take notice and fix it asap - perhaps a .NET 4.0 hotfix. This issue has been going on long enough starting .NET 2.0 (first time System.IO.Ports namespace was introduced).
It looks like what you're trying to do is send some data, then wait for a response, then repeat. You're using two threads for this and trying to sync them. I think you only need one thread. First send, then wait for a response, then repeat. This will eliminate your thread sync problems.