I am currently in a project involving data visualization of a signal captured from a device which has a Visual C++ API. I currently can log each datasample to file, but I'd like to do some sort of plot to screen.
I have had a previous successful experience with a similar job using socket between C++ and Python, but the code was lost. I have the Python socket "receiver" to reuse, but don't have the Visual C++ "sender" to reverse engineer or otherwise copy/paste.
My current Python code, which was working very fine, is:
import SocketServer
class SocketHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
## do something with 'data' here!
server = SocketServer.UDPServer(("192.168.1.23", 8888), SocketHandler)
server.serve_forever()
And the part of the Visual C++ that currently logs to file and I want to send to the socket is:
#include <fstream>
//(...lots of code...)
short int * dataBuff;
unsigned int dataNum;
int isAcqRunning;
int startFromTrg, stopFromTrg;
unsigned int firstSample, lastSample;
int errcode;
int i;
std::ofstream out("./out.txt");
// device->transferData is called inside a loop
// to get data from aquisition hardware's buffer
errcode = device->transferData(&dataBuff, &dataNum, &isAcqRunning,
&startFromTrg, &stopFromTrg,
&firstSample, &lastSample);
if(errcode == 0)
{
printf("\n Acquired samples: %d", dataNum);
for (i=firstSample; i<lastSample; i++)
out<<dataBuff[i]<<'\n'; /////// I'd like to send dataBuff[i] via socket!!
}
//(...lots of more code...)
Possibly useful additional information:
I'm using VisualStudio 2010 in Windows7;
This is the first time I touch C++ code in my life, I use Python almost exclusively;
I haven't have success trying to follow C++ examples from books and sites because, as it appears, C++ and VISUAL C++ are NOT the same thing and can behave very differently :o(
I thank very much for any help, and for reading this.
(EDIT: if there is a better way to do that without any additional complexity overhead for a noob, I would be glad to try. I like the socket stuff because it is language-transparent and solved a previous problem with very good speed)
Related
First off. This is not in any way a class assignment. This is my own personal work and research. I just want to get that out of the way.
I am learning how to use Matlab with various Arduino projects. I am a seasoned Matlab user but I am fairly new to the entire Arduino space.
I am trying to send some numerical data from Matlab (via a GUI) to my Arduino Uno and have the Arduino write it to my micro SC card. This is a temporary step to my larger project. However, there is no need to go into those specifics as they are outside of the scope of my issues.
I am fairly confident that the Matlab code works and the Arduino code is slightly modified from another project I did where I wrote and read random numbers from my micro SD card.
However, as I run the Matlab code, the Arduino blinks as if it is receiving the data but after I check the micro SD card it remains blank.
I am confident that my Arduino is wired correctly to my micro SD card adapter since this remains the same from my prior project.
Therefore, I am sure I am missing something trivial to get it to work.
I have researched several websites on the subject and their method and mine seem to align very well.
I am fairly certain the problem is in the conditional statement:
if (Serial.available() > 0) {
As you will see.
The Matlab code is below:
arduinoCom = serial('COM3', 'BaudRate', 115200);
sendData = 5;
fopen(arduinoCom);
fprintf(arduinoCom,'%i',sendData); %this will send 5 to the arduino
fclose(arduinoCom);
delete(arduinoCom);
The Arduino code is as follows:
#include <SD.h> // load SD library
int chipSelect = 4; // Chip select pin for the MicroSD Card Adapter
int incomingByte = 0; // for incoming serial data.
File SDF; // Serial data received is saved here.
void setup() {
Serial.begin(115200); // start serial connection to print out debug messages and data
pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode
while (!Serial) {
}
}
void loop() {
// Open file, Write data, Close file only when you receive data
if (Serial.available() > 0) {
incomingByte = Serial.read();
SDF = SD.open("SerialDataFile.txt", FILE_WRITE); // open "SerialDataFile.txt" to write data
SDF.println(incomingByte, DEC); // write ASCII-encoded decimal number to file
SDF.close(); // close file
}
}
The expected result would be a file "SerialDataFile.txt" stored on my micro SD card with the value 5.
Thank you for your help!
I have been trying to write a working program that takes in data from a UDP socket and displays it in an edit control box as you receive the data (My exposure to c++ is also only about a week :P have only done embedded C code before). I have a working program that can send and output data on a button click but I want something that can do it in real time. The aim is scale this up into a larger GUI program that can send control data to hardware and get responses from them.
I have run into various problems including:
The program just not executing my OnReceivefunction (derived from
CAsyncSocket)
Getting the OnReceive function to run on a separate thread so that it can still run after a button has been clicked sending a control packet to the client then waiting for a response in a while loop
Not being able to output the data in the edit box (tried using both CEdit and CString)
ReplaceSel error saying that the type char is incompatible with LPCTSTR
My code is based on this codeproject.com tutorial, being almost exactly what I want but I get the error in 4.
EDIT: the error in 4. disappears when I change it to a TCHAR but then it outputs random chinese characters. The codeproject.com tutorial outputs the correct characters regardless of char or TCHAR declaration. When debugged my code has type wchar_t instead type char like the other code.
Chinese output
In the working program echoBuffer[0] the character sent and displayed was a 1
UINT ReceiveData(LPVOID pParam)
{
CTesterDlg *dlg = (CTesterDlg*)pParam;
AfxSocketInit(NULL);
CSocket echoServer;
// Create socket for sending/receiving datagrams
if (echoServer.Create(12345, SOCK_DGRAM, NULL) == 0)
{
AfxMessageBox(_T("Create() failed"));
}
for (;;)
{ // Run forever
// Client address
SOCKADDR_IN echoClntAddr;
// Set the size of the in-out parameter
int clntAddrLen = sizeof(echoClntAddr);
// Buffer for echo string
char echoBuffer[ECHOMAX];
// Block until receive message from a client
int recvMsgSize = echoServer.ReceiveFrom(echoBuffer, ECHOMAX, (SOCKADDR*)&echoClntAddr, &clntAddrLen, 0);
if (recvMsgSize < 0)
{
AfxMessageBox(_T("RecvFrom() failed"));
}
echoBuffer[recvMsgSize] = '\0';
dlg->m_edit.ReplaceSel(echoBuffer);
dlg->m_edit.ReplaceSel(_T("\r\n"));
}
}
After reading the link that #IInspectable provided about working with strings and checking the settings differences between the two programs it became clear that the issue lay with an incorrect conversion to UNICODE. My program does not require it so I disabled it.
This has cleared up the issue in 4. and provided solutions for 2 and 3.
I also think I know why another instance of my program would not run OnReceivein 1. because that file was not being defined by one that was already being run by the program, but that is now irrelevant.
Hi i want to pass a data from my char device driver to serial port ttyS0..
I have created a simple char driver module which reads and write and it's my first tym doing it.. i am using debian guest os...
e.g.
echo "hello" > /dev/mydev
now when /dev/mydev receives the data it will then alter the string into something like "hello too" which is passed to my serial port /dev/ttyS0..
how can i alter the string?.. is it possible to use if statement inside mydev?
e.g
if(string=="hello"){
alterstringTO: hello to;
pass "hello to" /dev/ttyS0;
like echoing in terminal..
echo "hello to" > /dev/ttyS0
}
Is that possible?... or is there any other way doing it?
Here some of the code..
ssize_t dev_read(struct file *filp, char *buf, size_t clen, loff_t *f_pos){
short cnt =0;
while(clen && (msg[Pos]!=0))
{
put_user(msg[Pos],buf++);
cnt++;
clen--;
Pos++;
}
return cnt;
}
ssize_t dev_write(struct file *filp, const char *buf, size_t clen, loff_t *f_pos){
short dec = clen-1;
short cnt=0;
memset(msg,0,50);
Pos=0;
while(clen>0)
{
msg[cnt++] = buf[dec--];
clen--;
}
return cnt;
}
Thanks in advance..
Just a comment on writing to the serial port:
Remember the Linux foundations, everything is a file in Linux. To write to the device driver from a program you need to open the file for writing and then you can fprintf whatever data you want. You can do that from user space as well (the recommended way)
Refer to the following man pages:
man fopen
man fread/fwrite
man fprintf
man fclose
I'm not exactly sure what you are trying to achieve here, as the question and the intent seems unclear to me. I'll provide some guidance, but recommend that you edit your question and make it more readable.
Your snippet to compare strings is not correct. You can learn more about how to compare strings in C in here.
Altering a string in C is a basic operation that you learn when you start working with strings. This should help you getting started.
As final remark, please note that programming for the kernel requires extra care. A small mistake may lead to a crash and loss of data. If you really must, then the book Linux Device Drivers 3rd Edition is freely available and can help you further.
I am trying to ping a Socomec meter using the Modbus protocol, having researched, I found NModbus, a C# library. I have never used libraries or C# before (normally Java), but I have to dive right in.
I set myself up with Visual Studio Express for C# and installed .Net. I have copied then contents of the NModbus file into my project folder and added the references to the two main DLLs. Its didn't work with .Net 4, but I retargeted to 3.5 (and removed the Microsoft.Csharp reference) and things seemed to compile.
I am using this sample, below, to attempt to connect to the slave device. When I run this, and set the startAdress variable to the desired one (found in Socomec documentation) however all I get is a blank console window.
In short, am I using the correct method/parameters, is my setup/code incorrect? How do I connect to this meter?
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;
namespace NModbus
{
class SerialMaster
{
static void Main(string[] args)
{
ModbusSerialAsciiMasterReadRegisters();
}
public static void ModbusSerialAsciiMasterReadRegisters()
{
using (SerialPort port = new SerialPort("COM1"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
// create modbus master
IModbusSerialMaster master = ModbusSerialMaster.CreateAscii(port);
byte slaveId = 1;
ushort startAddress = 50536;
ushort numRegisters = 5;
// read five registers
ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
for (int i = 0; i < numRegisters; i++)
Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);
Console.ReadLine();
}
// output:
// Register 1=0
// Register 2=0
// Register 3=0
// Register 4=0
// Register 5=0
}
}
}
Why don't you use some Java MODBUS library when you are already familiar with Java? I haven't worked with Socomec meters, but in general for MODBUS devices you need to know the protocol and addresses you are interested in. Then try to read tags from the device with some tool that you know is working well, like MODPOLL. Then when you get usable values as expected, you go to programming the polling connection in any language you like. Otherwise, you risk to loose a lot of time wondering what's going on.
One hint... From your code I see that you are acting as MODBUS ASCII serial master. Although such devices exist, 95% of RS232/RS485 devices I worked with were MODBUS RTU. Read specification if you don't know the difference.
You can run Java applications as a Windows service. There is a Tomcat Java service starter that I use with my company's Java application. You have create a method that will be called to stop the service, but that's just a method.
Here's the line I use to install my application as a service --
"%~dp0windows\tomcat6" //IS//%1 --DisplayName %1 --Description "gmServer for %1" ^
--JavaHome "%JAVA_HOME%" --Classpath "%PR_CLASSPATH%" --LogPrefix gmserver ^
--StartMode jvm --StopMode jvm --Jvm auto --StartPath "%~dp0." ^
--LogPath "%~dp0." --LogLevel debug --StdOutput %1.out --StdError %1.err ^
--StartClass greenMonitor.gmServer --StartParams -I#%I#-u#3600 ^
--StopMethod windowsService --StopParams stop --StopTimeout 10
The caret characters ("^") are line continuations characters in .BAT files. You should be able to find the meanings of the Tomcat command line options with the Tomcat documentation.
And for a Java-based Modbus library, complete with lots of handy programs you can use to test the connection, check out j2mod on Sourceforge. My company did a fork of jamod, along with a bunch of cleanups and that was the result.
Has anyone had experience of using cocoaasyncsocket together with google protobuf? I want to seperate frames using a varint, which is simple enough using a client/server combo based on netty, but I don't see a simple way of decoding the initial varint when reading using cocoaasync.
On the C++ side of things, you'll have to use a combination of ReadVarint32() and VarintSize32() do something like this:
char buf[4];
buf = some_api_call(); /* _Copy/peak_ up to 4 bytes off the wire */
CodedInputStream cos(buf, sizeof(buf) - 1);
uint32_t frame_sz;
if (!cos.ReadInputStream(&frame_sz)) {
// Unable to read the frame size
return false;
}
frame_sz should have a valid value that will tell you how many bytes it needs to read.
uint32_t consumed_bytes = CodedOutputStream::VarintSize32(frame_sz);
Now you know how many bytes were consumed to generate frame_sz.
I'd wrap these calls in a library that I extern "C" and would link in from your application.