Serial COM Programming : Random Numbers - c++

i need a little help with my coding.. see the coding below is used if we were to write a string and send through a com port.. what if we were to generate random strings and send it through a com port.. what do i actually have to change in the "this->serialPort1->WriteLine(message);" ? tried several codes from google.. none of them are working
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
//add sender name
String^ name = this->serialPort1->PortName;
// grab text and store in send buffer
String^ message = this->textBox2->Text;
// write to serial
if(this->serialPort1->IsOpen)
//this->_serialPort->WriteLine(String::Format("<{0}>: {1}",name,message));
this->serialPort1->WriteLine(message);
else
this->textBox2->Text="Port Not Opened";
}

//Sorry for the bad format. Must learn how to use it correctly.
void createRandom(std::string & randString, const int len)
{
static const std::string theCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i)
{
//generate a random number which not bigger that max size of the available characters, then add it to the string.
randString += theCharacters[rand() % (sizeof(theCharacters) - 1)];
}
}
createRandom(message);
this->serialPort1->WriteLine(message);

Related

How save in an array the following 100 received value after a determined received string in Qt

I'm a newbie in C++ and Qt. I want to save in an array the value received in a serialport after I received the string: "Data".
I'm using the terminal example so the serialport works properly.
The read function in the Example is the same:
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
How can I modify it? thanks!!!
If your manual sending the data i recommend you add a start of frame delimiter and an end of frame delimiter and checksum preferably.
QByteArray packet_storage;
just declare it the where you declare serial.
StartOfMessage and EndOfMessage will depend on your device.
I don't know what your transmitting. Hopefully you can figure out from the documentation of your device what your sending out.
as for me i am using
enum Constants
{
StartOfMessage = '\x02', /* Value of byte that marks the start of a message */
EndOfMessage = '\x03', /* Value of byte that marks the end of a message */
CarridgeReturn = '\x0D', /* Carridge return is first byte of end of line */
LineFeed = '\x0A', /* Line feed is second byte of end of line */
NullChar = '\0' /* Null Character */
};
void MainWindow::readData()
{
// read all
QByteArray data = serial->readAll();
// store all read data packet_storage is a QByteArray
packet_storage.append(data);
int start_index = 0;
int end_index = 0;
// process packet if not empty
if(!packet_storage.isEmpty())
{
if( packet_storage.contains(StartOfMessage) && packet_storage.contains(EndOfMessage))
{
start_index = packet_storage.indexOf(StartOfMessage,0);
end_index = packet_storage.indexOf(EndOfMessage,0);
int length = 0;
for (int i=start_index; i <= end_index; i++)
{
length++;
}
// get data
QByteArray dt = packet_storage.mid(start_index,length);
// do your processing here.
// store in vector write to file etc.
processpacket(dt);
packet_storage.remove(start_index,dt.size());
}
}
}

Get struct from C++ dll into a C# application

I'm learning C# and have some experience with it. For a small project I need to implement a C++ dll into my C# app. It is a licenseplate recognition sdk.I can initialize it, so calling to this C++ code is working. But I have a problem to receive a struct back from the c++ code with strings in it. I tried a lot, read here a lot, but I don't get it working. This is C# side:
[DllImport("D:\\processor.dll", EntryPoint = "StartALPR", CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.LPStruct)]
public static extern TMyData StartALPR(TImageSource tImageSource);
The C# struct TMyData :
[StructLayout(LayoutKind.Sequential)]
public struct TMyData
{
[MarshalAs(UnmanagedType.LPTStr)]
public string PlateString;
[MarshalAs(UnmanagedType.LPTStr)]
public string PlateXML;
[MarshalAs(UnmanagedType.LPTStr)]
public string LastError;
};
And this is the method we call to send tImageSource which contains a string with a filepath to an image to analyze.
alprResult = StartALPR(tImageSource);
The file is analyzed, so that's working. I can see the plate strings in the output of VS2015.
But I'm expecting a struct "alprResult" back as defined in TMydata, but I get an exception that the method sign is not compatible with the pinvoke sign. The only information I have is an example of how to use this dll/code in C++. This is the C++ code :
TImageSource SImageSource;
TMyData *pd;
/* Set input image */
SImageSource.MyImageFile = AnsiString(CarImage).c_str();
Memo1->Lines->Clear();
/* Starting plate detect and recognition */
pd = StartALPR(&SImageSource);
/* Standard XML result, the plate datas with numbers and positions */
Memo1->Lines->Add(pd->PlateXML);
/* last error message */
Memo2->Lines->Add(pd->LastError);
/* Best characters on plate */
Edit1->Text = pd->PlateString;
This is the C++ struct from the same example :
struct TMyData;
typedef TMyData *PMyData;
struct TMyData
{
/**
PlateString: Best license plate number of the plate group
*/
const char * PlateString;
/**
PlateXML: Plate group data in standard XML string
*/
const char * PlateXML;
/**
LastError: Laast config error ex: bad file extensions .. Default: empty
*/
const char * LastError;
};
How can I use this in C#?
Thanks in advance.
I actually had to solve a similar issue to this recently. I simply serialized the data into a struct and shipped it over a local zeromq socket.
//
// Weather update server in C++
// Binds PUB socket to tcp://*:5556
// Publishes random weather updates
//
// Olivier Chamoux <olivier.chamoux#fr.thalesgroup.com>
//
#include <zmq.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if (defined (WIN32))
#include <zhelpers.hpp>
#endif
#define within(num) (int) ((float) num * random () / (RAND_MAX + 1.0))
int main () {
// Prepare our context and publisher
zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
publisher.bind("ipc://weather.ipc"); // Not usable on Windows.
// Initialize random number generator
srandom ((unsigned) time (NULL));
while (1) {
int zipcode, temperature, relhumidity;
// Get values that will fool the boss
zipcode = within (100000);
temperature = within (215) - 80;
relhumidity = within (50) + 10;
// Send message to all subscribers
zmq::message_t message(20);
snprintf ((char *) message.data(), 20 ,
"%05d %d %d", zipcode, temperature, relhumidity);
publisher.send(message);
}
return 0;
}
and now the client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using ZeroMQ;
namespace Examples
{
static partial class Program
{
public static void WUClient(string[] args)
{
//
// Weather update client
// Connects SUB socket to tcp://127.0.0.1:5556
// Collects weather updates and finds avg temp in zipcode
//
// Author: metadings
//
if (args == null || args.Length < 2)
{
Console.WriteLine();
Console.WriteLine("Usage: ./{0} WUClient [ZipCode] [Endpoint]", AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine();
Console.WriteLine(" ZipCode The zip code to subscribe. Default is 72622 Nürtingen");
Console.WriteLine(" Endpoint Where WUClient should connect to.");
Console.WriteLine(" Default is tcp://127.0.0.1:5556");
Console.WriteLine();
if (args.Length < 1)
args = new string[] { "72622", "tcp://127.0.0.1:5556" };
else
args = new string[] { args[0], "tcp://127.0.0.1:5556" };
}
string endpoint = args[1];
// Socket to talk to server
using (var context = new ZContext())
using (var subscriber = new ZSocket(context, ZSocketType.SUB))
{
string connect_to = args[1];
Console.WriteLine("I: Connecting to {0}…", connect_to);
subscriber.Connect(connect_to);
/* foreach (IPAddress address in WUProxy_GetPublicIPs())
{
var epgmAddress = string.Format("epgm://{0};239.192.1.1:8100", address);
Console.WriteLine("I: Connecting to {0}…", epgmAddress);
subscriber.Connect(epgmAddress);
}
} */
// Subscribe to zipcode
string zipCode = args[0];
Console.WriteLine("I: Subscribing to zip code {0}…", zipCode);
subscriber.Subscribe(zipCode);
// Process 10 updates
int i = 0;
long total_temperature = 0;
for (; i < 20; ++i)
{
using (var replyFrame = subscriber.ReceiveFrame())
{
string reply = replyFrame.ReadString();
Console.WriteLine(reply);
total_temperature += Convert.ToInt64(reply.Split(' ')[1]);
}
}
Console.WriteLine("Average temperature for zipcode '{0}' was {1}°", zipCode, (total_temperature / i));
}
}
}
}

How do I convert my GPS NEMA sentences to a string using an Arduino?

I am attempting to parse information from a GPS module using an Arduino Uno. My thought was to convert the NEMA sentences to strings, then use a simple code to split the comma separated text into groups. Once that is accomplished I can then display certain portions of those groups to a screen.
Is this possible? I have included my very simple code below. Please keep in mind I am a beginner when it comes to code.
int rxPin = 0; // RX PIN
int txPin = 1; // TX TX
String text = Serial.read();
String message = text;
int commaPostion;
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
Serial.begin(4800);
Serial.println(message);
do{
commaPosition = message.indexof(',');
if(commaPosition != -1)
{
Serial.println(message.substring(0,commaPosition));
message = message.substring(commaPosition+1, message.length());
}
else
{ //here after last comma is found
if(message.length() > 0)
Serial.println(message);
}
while(commaPosition >=0);
{
}
void loop() {
}
In programming, laziness is a virtue. Why reinvent the wheel, right?
Check out the TinyGPS library designed to do exactly what you're trying to accomplish.

File.getFilename() in Arduino?

UPDATE:There's no getfilename(), but there's name() function!
I'm trying to make a simple program to store all filenames in a String array and then show them in the LCD.
Code:
String* list(File root, int len) {
if (!root.isDirectory()) return NULL;
String files[50];
int i = 0;
while (true) {
File f = root.openNextFile();
if (i < 50) files[i] = f.getFilename();
f.close();
i++;
}
len = i;
root.close();
return files;
}
Code to display in LCD:
void displayToLCD(String* files, int len) {
lcd.clear();
lcd.home();
lcd.print("Files on SD:");
for (int i = 0; i < len; i++) {
lcd.setCursor(0, 1);
lcd.print(files[i]);
delay(1000);
}
lcd.clear();
lcd.home();
}
But the problem is that the class File doesn't have the 'getFilename()' function. Is there any way to get the filename?
Please help.
Best regards,
Mateiaru
Just remembered that that on arduino.cc at File section, at openNextFile example, they use File.name()! So there's no getFilename().
Mateiaru
I would recommend that you look at my MP3 FilePlayer.ino example. It accomplishes what you are attempting, but just to the serial port.
Additionally it won't run out of memory, as it does not store the file names into an array or memory. Rather displays them and lets the user select the number. This can also be readily adapted to an up/down arrow menu, for an LCD.
Note that I am using SdFat. It has more functions and attributes that are not made public in standard SD. along with the file.getFilename() .

Why is this encrypted message damaged?

I use the following code to encrypt a string with a key, using the 3-DES algorithm:
private bool Encode(string input, out string output, byte[] k, bool isDOS7)
{
try
{
if (k.Length != 16)
{
throw new Exception("Wrong key size exception");
}
int length = input.Length % 8;
if (length != 0)
{
length = 8 - length;
for (int i = 0; i < length; i++)
{
input += " ";
}
}
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.Zeros;
des.Key = k;
ICryptoTransform ic = des.CreateEncryptor();
byte[] bytePlainText = Encoding.Default.GetBytes(input);
MemoryStream ms = new MemoryStream();
CryptoStream cStream = new CryptoStream(ms,
ic,
CryptoStreamMode.Write);
cStream.Write(bytePlainText, 0, bytePlainText.Length);
cStream.FlushFinalBlock();
byte[] cipherTextBytes = ms.ToArray();
cStream.Close();
ms.Close();
output = Encoding.Default.GetString(cipherTextBytes);
}
catch (ArgumentException e)
{
output = e.Message;
//Log.Instance.WriteToEvent("Problem encoding, terminalID= "+objTerminalSecurity.TerminalID+" ,Error" + output, "Security", EventLogEntryType.Error);
return false;
}
return true;
}
I send the output parameter as is over to a WCF http-binding webservice, and I noticed that the actual encoded string looks different, it looks like there are some \t and \n but the charachters are about the same.
What is going on, why does the server get a different encoded string?
Usually cipher text is base64 encoded in an effort to be binary safe during transmission.
Also I would not use 3DES with ECB. That is awful, you must have copy pasted this from somewhere. Use AES with cbc mode and think about adding a cmac or hmac.