I have an Arduino XBee shield and I have a Sparkfun XBee USB explorer. I would like to send data (temperature sensor) that comes from the Ardunio XBee and receive it in my C# programme.
For now, let's say I want to send 45, 100 to my C# programme.
I don't receive any data that comes from the XBee shield. Am I missing anything with the code?
The below code is the sender from the Arduino XBee shield:
SoftwareSerial mySerial(4,5);
void setup()
{
mySerial.begin(9600);
}
void loop()
{
if (mySerial.available() > 0)
{
mySerial.write(45);
mySerial.write(',');
mySerial.write(100);
mySerial.write('\n');
}
}
Receiver code for the USB XBee explorer in C#:
SerialPort port = new SerialPort();
public Form1()
{
try
{
port.PortName = "COM8";
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
Console.WriteLine("Opened");
}
catch(Exception ex)
{
Console.WriteLine("Sorry! " + ex);
}
// Handler for receiving data
port.DataReceived += serialPort1_DataReceived;
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (port.IsOpen == true)
{
string RxString = port.ReadLine();
Console.WriteLine(RxString);
}
}
The XBee configuration:
One XBee is: Coordinator AT mode -- connected to USB Sparkfun Explorer
Another XBee is: Router AT mode -- Connected to Arduino shield
As tomlogic answered my question in Stack Overflow question XBee two-way communication (sender and receiver) at the same time.
I got it working. The problem was from my void loop() method. The mySerial should be like
mySerial.println(temperature);
However, you must check mySerial Rx,Tx pin that they are right one
Your XBee shield uses pins 0 and 1 on the Arduino. Softwareserial is not needed, just use:
Serial.begin(9600); // In void setup() routine
To send the temperature, use this in function loop:
Serial.print(temperature); // Need a variable 'temperature' of course...
Test the Arduino code with the built-in terminal in the Arduino IDE to see if the port actually can receive and send (remove the XBee shield first). After that works, test out the XBee communication.
Related
I think I missed something in my code.
Below is my code in C#
public Form1()
{
InitializeComponent();
serialPort1.PortName = "COM2";
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.RequestToSend;
serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
serialPort1.NewLine = System.Environment.NewLine;
}
private void btnSend_Click(object sender, EventArgs e)
{
serialPort1.Open();
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
string num = "+639952006630\n";
serialPort1.Write(num);
string message = "Your child arrived at our school at " + DateTime.Now + ".";
serialPort1.Write(message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Below is my code in Arduino for sending data using GSM module SIM800L
#include <SoftwareSerial.h>
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 8
//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 7
//Create software serial object to communicate with SIM800
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);
void setup() {
//Begin serial comunication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
while(!Serial);
//Being serial communication with Arduino and SIM800
serialSIM800.begin(9600);
delay(1000);
//Set SMS format to ASCII
serialSIM800.write("AT+CMGF=1\r\n");
delay(1000);
//getting the number
char remoteNum[20]; // telephone number to send sms
readSerial(remoteNum);
//Send new SMS command and message number
serialSIM800.print("AT+CMGS=\"");
serialSIM800.print(remoteNum);
serialSIM800.print("\"\r\n");
delay(1000);
// getting sms text
char txtMsg[200];
readSerial(txtMsg);
//Send SMS content
serialSIM800.print(txtMsg);
delay(1000);
//Send Ctrl+Z / ESC to denote SMS message is complete
serialSIM800.write((char)26);
delay(1000);
Serial.println("SMS Sent!");
}
/*
Read input serial
*/
char readSerial(char result[]) {
int i = 0;
while (1) {
while (Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == '\n') {
result[i] = '\0';
Serial.flush();
return 0;
}
if (inChar != '\r') {
result[i] = inChar;
i++;
}
}
}
}
void loop() {
}
My confusion/question here is
Whenever I test it using Serial Monitor in Arduino, the code in Arduino sends message to the cellular number successful. But when I use a form in Visual Studio using C#, nothing happens. There are also no errors that appear. I tried F11 also to know if I am missing an error, still I see nothing. But the application does not send SMS to the number.
Help from you guys is very much appreciated. Thank you in advance.
The solution is as obvious as simple. You have all your routines in the Arduino setup which runs only once. So sending one sms from Arduino directly works exactly 1 time.
When connecting via c code, the Arduino is already booted and in the EMPTY loop. So the chance to hit the one time run code is zero.
Put your routines especially
readSerial(remoteNum);
in the loop and it should work as expected.
The first thing you should do before sending the commands with your Visual Studio is that the serialport is correctly configured, you simply have the serial port closed loop, everything you send should receive, If you do not receive anything you have a serial port configuration problem
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.
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);
}
}
}
I am prototyping a sort of Arduino-based docking station for a tablet, using the USB port as connector. This means I need to support to ability to plug/unplug the USB connector while the application on the tablet is running.
The tablet runs a c# application (.net 4.5 on Win7 64 bit) in which I am connecting to the Arduino Uno. When the application is launched I loop all available COM ports using:
var ports = SerialPort.GetPortNames(); // -> [COM3,COM4,COM8]
foreach (var port in ports)
{
var serial = new SerialPort(portname, baudRate);
//attempt handshake and connect to right port
}
This work fine, but if I unplug and replug the USB cable and reattempt to reconnect to the Arduino (while the application is still running), the Arduino port (COM8) is no longer listed in:
SerialPort.GetPortNames(); // -> [COM3,COM4] and no COM8
Even restarting the application (with the Arduino replugged) will result in only [COM3,COM4] being listed.
The only way to get it back to work is to unplug and replug the Arduino while the application is not running.
What confuses me is the fact that when I plug in the Arduino Uno after starting the application, the SerialClass does recognize the newly added port and allows me to connect.
The problem only occurs when I unplug and replug the device when the application is running. It seems that despite the ability to reset the COM port (in code or manually in device manager), the SerialClass (and native Win32_SerialPort - I checked this too) do not recognize this, unless I restart the application
What could be the reason for this? And how can I make sure that my application can reconnect to that port? Are there any alternatives to using the SerialPort to handle the USB connector?
I found a solution that can handle plugging and unplugging a SerialPort.
First of all, it requires the use the SafeSerialPort, which allows you to dispose the serial port properly.
SafeSerialPort serialPort;
private void Connect()
{
string portname = "COM8";
serialPort = new SafeSerialPort(portname, 9600);
serialPort.DataReceived += port_DataReceived;
serialPort.Open();
}
Second, you need to use LibUsbDotNet to detect whether a USB device is connected or disconnected. This will allow you to determine whether to connect to the device or reset the COM port.
public UsbDevice MyUsbDevice;
//Find your vendor id etc by listing all available USB devices
public UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x2341, 0x0001);
public IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
private void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
{
if (e.Object.ToString().Split('\n')[1].Contains("0x2341"))
{
if (e.EventType == EventType.DeviceArrival)
{
Connect();
}
else if(e.EventType == EventType.DeviceRemoveComplete)
{
ResetConnection();
}
}
}
Finally, disposing the SerialPort will makes sure it is registered by Windows in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM, meaning that SerialPort.GetPortNames() can re-detect the port.
private void ResetConnection()
{
try
{
//Send any data to cause an IOException
serialPort.Write("Any value");
}
catch (IOException ex)
{
//Dispose the SafeSerialPort
serialPort.Dispose();
serialPort.Close();
}
}
After this process, you can simply reconnect to the COM port when the USB device is connected without the need to restart the application.
Full code:
using LibUsbDotNet;
using LibUsbDotNet.DeviceNotify;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;
SafeSerialPort serialPort;
public SerialPortTest()
{
Connect();
UsbDeviceNotifier.OnDeviceNotify += OnDeviceNotifyEvent;
}
private void Connect()
{
string portname = "COM8";
serialPort = new SafeSerialPort(portname, 9600);
serialPort.DataReceived += port_DataReceived;
serialPort.Open();
}
private void ResetConnection()
{
try
{
serialPort.Write("Any value");
}
catch (IOException ex)
{
serialPort.Dispose();
serialPort.Close();
}
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(serialPort.ReadExisting());
}
public UsbDevice MyUsbDevice;
//Vendor ID etc can be found through enumerating the USB devices
public UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x2341, 0x0001);
public IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
private void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
{
//if this is your usb device, in my case an Arduino
if (e.Object.ToString().Split('\n')[1].Contains("0x2341"))
{
if (e.EventType == EventType.DeviceArrival)
{
Connect();
}
else
{
ResetConnection();
}
}
}
So I believe this is happening because your program is caching the address of the USB the first time it is plugged in.
When someone plugs in a device, the hub detects voltage on either D+
or D- and signals the insertion to the host via this interrupt
endpoint. When the host polls this interrupt endpoint, it learns that
the new device is present. It then instructs the hub (via the default
control pipe) to reset the port where the new device was plugged in.
***This reset makes the new device assume address 0, and the host can
then interact with it directly; this interaction will result in the
host assigning a new (non-zero) address to the device.
Your best bet is to research how to programically flush the address cache of USB devices.
Reference:http://en.wikipedia.org/wiki/USB_hub
Im trying to read the output of a device on a COM port on my PC.
Im wrote a C# program to do so.
Using PuTTY, I can see the output Im expecting from my device.
The problem is that the function SerialPort.ReadExisting(); in my DataReceived function gives my a completely different string.
What is the proper way to read from a COM port using SerialPort?
Also, the strings I get from SerialPort.ReadExisting(); are fragments of the string I sent to the device.
Below is the code that initializes the SerialPort.
SerialPort port;
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string data = port.ReadExisting();
}
void init_serialport(object sender, EventArgs e)
{
if (port != null)
{
port.Close();
}
port = new SerialPort( /* ... */ );
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Handshake = Handshake.RequestToSend;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
try
{
port.Open();
}
catch (Exception ex)
{
// ...
}
}
the strings I get from SerialPort.ReadExisting(); are fragments of the string I sent to the device.
I'd have a look at SerialPort.ReceivedBytesThreshold.
"Gets or sets the number of bytes in the internal input buffer before a DataReceived event occurs."
I would first take a look at the Read method of the port object, look at the raw bytes and verify that they match your expectations, which would then narrow down the problem to the encoding on the conversion to string.
More information on this is provided here.
You received fragments because SerialPort.Existing() executes and completes in less time then it takes for your sending device to send the entire string.
You need to repeat the call continuously or until you received the end of string character if the string has one.