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.
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 am still struggling to be able to read incoming response messages from a piece of hardware my program is communicating with.
I am using a GSocketClient and am able to connect and successfully send messages using g_output_stream_write(). I then want to read the response sent back from the device, but I have no way of knowing how many bytes the reply will be in order to use g_input_stream_read(). I have also tried using g_input_stream_read_all(), but this seems to block the application and never return. I don't know how g_input_stream_read_all() determines that it has reached the end of a stream, but I assume the problem is somewhere there?
I know that there is incoming data because I can use g_input_stream_read() with a made-up byte size like 5 and I then see the first 5 incoming bytes, but the response size will always be different.
So my questions is, is there a way to determine how much data is waiting to be read so that I can plug that into g_input_stream_read() as a variable for the size to read? And if not, what is the correct usage of g_input_stream_read_all() to get it to not block like I am seeing it do?
Does something like the following work?
#define BUF_SIZE 1024
guint8 buffer[BUF_SIZE];
GByteArray *array = g_byte_array_new();
gsize bytes_read;
GError *error = NULL;
while (g_input_stream_read_all(istream, buffer, BUF_SIZE, &bytes_read, NULL, &error))
{
g_byte_array_append(array, buffer, bytes_read);
if (bytes_read < BUF_SIZE)
/* We've reached the end of the stream */
break;
}
if (error)
// error handling code
It's some kind of annoying:
Since I started using the MPMoviePlayerController the console is overfilled with information from MPAVController.
Eg:
[MPAVController] Autoplay: _streamLikelyToKeepUp: 1 -> 1
[MPAVController] Autoplay: Disabling autoplay
This is some kind of annoying because I always have to search for my own logged information.
Is there a way to turn off logging for specific objects or frameworks?
I don't think such filtering is possible out of the box. But it's possible to redirect stderr (which is used by NSLog) into a pipe, read from that pipe in a background thread and then print messages that pass through the filter onto stdout (which is captured by the debugger as well). This code does the job:
int main(int argc, char *argv[])
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void) {
size_t const BUFFER_SIZE = 2048;
// Create a pipe
int pipe_in_out[2];
if (pipe(pipe_in_out) == -1)
return;
// Connect the 'in' end of the pipe to the stderr
if (dup2(pipe_in_out[1], STDERR_FILENO) == -1)
return;
char *buffer = malloc(BUFFER_SIZE);
if (buffer == 0)
return;
for (;;)
{
// Read from the 'out' end of the pipe
ssize_t bytes_read = read(pipe_in_out[0], buffer, BUFFER_SIZE);
if (bytes_read <= 0)
break;
// Filter and print to stdout
if (should_show(buffer)) // TODO: Apply filters here
fwrite(buffer, 1, bytes_read, stdout);
}
free(buffer);
close(pipe_in_out[1]);
});
// Rest of main
}
Please note that this code is quite simple and doesn't handle all corner cases. First of all it captures all stderr output and not just NSLog. Maybe this could be filtered out by checking against the content. NSLog output always starts with the date and time.
Second problem with this code is that it doesn't try to split/join strings it reads from the pipe. There's no guarantee that there will be one NSLog per read. They could be coming together or be too long and would be split. To handle this it would require additional processing of the data read from the pipe.
Anyway, for many practical purposes this should be enough.
You should look into NSLogger. While NSLog doesn't give you any selectivity about what you see from run to run, NSLogger can. NSLogger displays output from the device (or simulator) in its own window in OS X.
Basically it adds the concept of facility and level to output. Unix wizards might find fault with this comparison but I see it as very similar to syslog. The NSLogger viewer lets you display output messages for one or more facilities (which you define) which also meet the minimum level required.
Macros define what you see in the output window. Here's an excerpt:
#ifdef DEBUG
#define LOG_GENERAL(level, ...) LogMessageF(__FILE__,__LINE__,__FUNCTION__,#"general",level,__VA_ARGS__)
#else
#define LOG_GENERAL(...) do{}while(0)
#endif
When DEBUG is off, no messages appear. When on, if you have a LOG_GENERAL() statement in code and your viewer is configured to display facility "general" and your level is sufficient to be displayed, you get a message.
It's incredibly flexible and I like it a lot. It takes about five minutes to add to your project. Please take a look at the github page linked above for full details and download.
(This will not solve the problem of MPAVController filling the console with messages, but it does put the messages you want in a new window, making it much easier to control, filter and interpret what you are interested in.)
Another option, if you can use it, is to run either a simulator or a device running iOS < 6.0.
The MPAVController log messages do not appear for me when using a 5.0 device or the 5.1 Simulator. But they definitely appear in the 6.0 Simulator.
Of course one should generally use the current OS, but if one is working on a video heavy section of a project, running an earlier simulator or device while working on that particular set of tasks is a way to alleviate this logging headache.
This also provides some backward compatibility testing as a bonus.
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)
I am writing an UDP client/server programs in C on linux. The thing is that I must add connection check feature. in linux man pages i found example of udp client with this feature( http://www.kernel.org/doc/man-pages/online/pages/man3/getaddrinfo.3.html ). It uses write/read functions to check server response. I tried to apply it to my program, and it looks like this:
char *test = "test";
nlen = strlen(test) + 1;
if (write(sock, test, nlen) != nlen) { // socket with the connection
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sock, buf, nlen);
if (nread == -1) {
perror("Connection");
exit(EXIT_FAILURE);
}
the problem is than than i execute program with this bit when server is on, it does nothing except reading input infinite time which it doesn't use too. I tried kill(getpid(), SIGHUP) interrupt, which i found other similar topic here, and shutdown(sock, 1), but nothing seems to work. Could you please tell me a way out how to stop the input read or any other possible option to check if udp server is active?
You should use asynchronous reading.
For this you must use the select() function from "sys/socket.h".
The function monitors the socket descriptor for changes without blocking.
You can find the reference for it here or here or by typing "man select" in your console.
There is an example here for Windows, but its usage is very similar to UNIX.