SerialPort & CCS String Communication - c#

I'm trying to send/receive a string through C#, in C# i just do:
SerialPort.WriteLine("A6");
but in CCS, if i try sending a string char after char it does not work at all, neither with ReadLine nor with ReadExisting! This is what i have tried creating an array, so that everytime we enter the RXBUFF pragma, we add the received char to the array, until the array is full (i randomly defined the array size to be 2, which means we deal with 2-char-length strings), and eventually send the string by sending char after char:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
if(__even_in_range(UCA1IV,18) == 0x02){ // Vector 2 - RXIFG
if(counter==0)
{
Data[0]=UCA1RXBUF;
counter++;
}
else
{
Data[1]=UCA1RXBUF;
counter=0;
UCA1TXBUF=Data[0];
while(!(UCA1IFG & UCTXIFG)); // until UCTXBUF1 is empty
UCA1TXBUF=Data[1];
}
}
in C#:
listBox2.Items.Add(SerialPort.ReadExisting());
i get non-sense text, like : ??A??? sometimes : ????A? etc.., but with:
listBox2.Items.Add(SerialPort.ReadLine());
in the first time i press the Send button which sends the "A6", i get nothing, the second time i get non-sense aswell , just like the ReadExisting behavior.
by the way, even if i try to send the string in the easiest way (without array and conditions), i mean like this:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
UCA1TXBUF='A';
while(!(UCA1IFG & UCTXIFG)); // until UCTXBUF1 is empty
UCA1TXBUF='6';
i also get inconsistent items in the listbox.
However, if i do this:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
UCA1TXBUF=UCA1RXBUF;
i do get "A6" in the listbox and everything just work fine (with ReadLine and ReadExisting)!
could anyone just tell me why this is happening?

I'v just neutralized the Parity bit, everything works now, Thank you all!

This indicates that you shouldn't be waiting for the TX flag inside the RX ISR. The RX interrupt routine should simply fill a FIFO buffer (a byte queue), so that you can parse its contents somewhere else (main routine?), and then create a response when needed.
Pseudo code for the RX ISR should be something like:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
FIFO_Enqueue(&RxBuffer, UCA1RXBUF);
And somewhere inside the main() loop you can parse its contents:
while (1)
{
// find the first occurrence of "A6" and dequeue it
if (FIFO_StartsWith(&RxBuffer, "A6")
SendResponse();
}

Related

Get resource hex/ascii \n\r value not converted one

Greeting,
We have some translation stored in a resx file which contains a break line similar to:
"This is a Test
& or something similar. "
There are ~50 devs in our project and from time to time Visual studio corrects the translation into
"This is a Test
& or something similar. " causing our pipeline to fail (long story)
Now my goal is to write a test and to ensure that the translations are not "corrupted", but I found no way to get the actual hex or ASCII value of the string above.
It always comes as \n\r .
I also want to mention that I would like not to change the current behavior of the app, only to get the proper ASCII or hex from the resource
This is what I would like to get from the resx file using: GetString or similar
&# xA;&# xD;
&# 13;&# 10;
[TestMethod]
public void Test()
{
// Arrange
var x = ToLiteral("This is a Test
&& or something similar.");
// Act
var xExpected = ToLiteral(Resources.Something.Some_Title);
// Assert
x.ShouldBe(xExpected );
}
private static string ToLiteral(string valueTextForCompiler)
{
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(valueTextForCompiler, false);
}

how to find word using a file c#

My message box displays hi and his, whenever, my file has the word hello.
My project is supposed to display the messagebox hi only,
and for my code (rtbDisplay.Text = "\n"+"hey";) it override the hello word that
I type.
My project is to create a chatbox. Whenever i type in certain word, it will reply me back with the words that i choose.
File.AppendAllLines(#"C:\\Users\\L31011\\Desktop\\version17\\version17\\FinalProject\\WinRecognize\\bin\\Debug\\Chat\\messages.txt", new[] { rtbType.Text });
StreamReader sr = new StreamReader("C:\\Users\\L31011\\Desktop\\version17\\version17\\FinalProject\\WinRecognize\\bin\\Debug\\Chat\\messages.txt");
rtbDisplay.Text = sr.ReadLine();
//here
string record;
string input = "hello";
string input1 = "goodbye";
try
{
record = sr.ReadToEnd();
while (record != null)
{
if (record.Contains(input))
{
MessageBox.Show("hi");
//rtbDisplay.Text = "\n"+"hey";
}
if (record.Contains(input1))
{
MessageBox.Show("byebye");
}
else
{
MessageBox.Show("his");
}
break;
}
}
finally
{
sr.Close();
}
There are a whole bunch of things that you can do to this. First, the #"string goes here" construct (i.e., with an "at" sign as a preface to the string) means that there is no escaping needed. So you don't need to double up your backslashes (I've been writing in C# since the alpha at the end of 2000, and I didn't realize that #"c:\\some\\file.ext" would work). You can say either "c:\\some\\file.ext" or #"c:\some\file.ext" -- but #"c:\\some\\file.ext" is just weird (and too much typing).
You should read up on using using. It's simpler and clearer than try { } finally { CloseOrDispose() }.
Then there is what #ChetanRanpariya is talking about. Put a breakpoint on the first if statement, when there is "hello" somewhere in the second line to the end. Start single-stepping. Notice that you step into the first message box because of the "hello". Then continue stepping. You don't step into the second message box, because there's no "goodbye". But, there is an else. See what happens next.
By the way, is this really what you want to do? You read the first line, stick it in a text box. Then you read lines 2 through N (all in one go, and into one string) and check to see if "hello" or "goodbye" is on any of them - all in a while loop that will only ever be executed once.

Turn on/off WiFi hotspot programmatically

I need help in creating a C# script that set a android WiFi in hotspot mode. Here is the code that I managed to create.
public bool setAPEnabled(bool enabled)
{
using (AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"))
{
try
{
if(isWifiEnabled()==true){
setWifiEnabled(false);
}
using (var wifiManager = activity.Call<AndroidJavaObject>("getSystemService", "wifi"))
{
return wifiManager.Call<bool>("setWifiApEnabled",null, enabled);
}
}
catch (Exception e)
{
}
}
return false;
}
Everything works well - but I have a problem with setting the SSID and password. After reviewing the documentation I know that I have to replace my null value with the settings object, but I completely don't know how to do it in Unity.
Theses methods works only for android 5.0 and less !
The EASY way :
Try instantiating the WifiConfiguration first :
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
Now you can call methods and set/get fields within this object :
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
After settings all of the required fields just call your setWifiApEnabled method :
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
Maybe you will have to set more fields than these two but to confirm that you should check the source and ensure what setWifiApEnabled method does internaly.
The HARD way :
( using reflection code )
Step 6 does not work for android 5.0+ !
Using reflection with AndroidJavaObject can be a bit tricky because you have to remember to dispose every object.
So from the beginning :
// android code for that should look like :
// wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
// but in Unity C# you have to split this into few chunks:
// 1. Get calling class :
using ( AndroidJavaObject classObj = wifiManager.Call<AndroidJavaObject>("getClass") )
{
// classObj should contains your class object
// 2. call get WifiConfiguration class details :
using ( AndroidJavaObject wifiConfiguration = new AndroidJavaObject("setWifiApEnabled") )
{
// 3. Fill that object :
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
// 4. Get WifiConfiguration class definition
using (AndroidJavaObject wifiCfgClass = wifiConfiguration.Call<AndroidJavaObject>("getClass") )
{
// 5. Get boolean definition
using ( AndroidJavaObject booleanObj = new AndroidJavaObject("java.lang.Boolean") )
{
using ( AndroidJavaObject booleanClass = booleanObj.Call<AndroidJavaObject>("getClass") )
// 6. Get method definition
using ( AndroidJavaObject methodObj = classObj.Call<AndroidJavaObject>("getMethod", "setWifiApEnabled", wifiCfgClass , booleanClass))
{
// 7. Call that method :)
methodObj.Call("invoke", wifiManager, wifiConfiguration, enabled);
}
}
}
}
}
WifiConfiguration :
I was trying to find out why the above code might not work but for me it was working okay ( tested on some virtual machines and Samsung Galaxy S5 Neo ).
What may be the case ( which I found out at almost midnight ) is a passphrase.
According to this wikipedia article in the section about WPA-PSK
Also referred to as WPA-PSK (pre-shared key) mode, this is designed for home and small office networks and doesn't require an authentication server.[9] Each wireless network device encrypts the network traffic using a 256 bit key. This key may be entered either as a string of 64 hexadecimal digits, or as a passphrase of 8 to 63 printable ASCII characters.[10] If ASCII characters are used, the 256 bit key is calculated by applying the PBKDF2 key derivation function to the passphrase, using the SSID as the salt and 4096 iterations of HMAC-SHA1.[11] WPA-Personal mode is available with both WPA and WPA2.)
My suggestion would be to use the same passphrase as in the article linked above to make sure it's valid.
Also another thing to note is the SSID part which has a short but good description here on wikipedia.
A common, albeit incorrect assumption, is that an SSID is a string of human-readable characters (such as ASCII), terminated by a NUL character (as in a C-string). SSIDs must be treated and handled as what they are, a sequence of 0–32 octets, some of which may not be human-readable
From what I've checked you do not need to null-terminate your string within Java or C# because it will be handled by native code but still you should not exceed 31 characters ( 32 will be the null character ).
I checked this with :
SSID:MeHotSpot
WPA-PSK:5260305714217573

Checking the values of a dictionary against a string being read in externally

I've created a dictionary like so:
public Dictionary<string, string> myValues = new Dictionary<string, string>();
Then in my start method I'm filling out my dictionary like so:
void Start()
{
myValues.Add("device one", "11111111111111");
}
And what I'm trying to do is check the value that I've created in my dictionary, in the above example it would be the 1111111111111, against a string value that is being read in remotely. The check I'm doing is this:
void Update ()
{
// Spawn a model based on the signal the ipad has recievied.
if( myValues["device one"] == outputContent.text)
{
Instantiate(model1, new Vector3(-2.5f, 3.0f,0), Quaternion.identity);
}
}
The message is getting parsed from a wrapper class that takes information from native ipad stuff and passes it direct to unity. The method for getting the message is this:
private void AppendString(string message)
{
outputContent.text += "\n" + message;
}
Now, the thing is, the message getting passed works. When I run my code, the screen gets filled with the information I want. But when I try to check the values I've stored against the ones getting sent in, nothing happens.
How I got my initial hard coded value was by first reading them in from the AppendString method. And I've double checked them to make sure I've got the correct information down.
Can someone please tell me if I'm comparing the values held within my dictionary, to those being read in, is correct?
There's a couple of 'suspicious' spots.
Here, you add \n, are you sure that's included in the dictionary's value?
outputContent.text += "\n" + message;
Also, make sure you compare the strings properly. It may even be a capitalization problem, something that's bitten me many times. Try for instance:
if(String.Equals(myValues["device one"], outputContent.text, StringComparison.OrdinalIgnoreCase)
better replace following line
if( myValues["device one"] == outputContent.text)
with:
if( myValues["device one"].Equals(outputContent.text))

ValueType to IntPtr to use during application lifetime

Lets say we have a native library that works with data like this:
double *pointer = &globalValue;
SetAddress(pointer);
//Then we can change value and write it to disk
globalValue = 5.0;
FlushValues(); // this function writes all values
// registered by SetAddress(..) functions
... //Then we change our value (or values)
FlushValues(); //and do write any time we need
Now I have to interop it to C#. I would like to avoid using unsafe... but... I dont know =)
So on C# side we will have some class wich fields we will write. And we can do writing like:
public class Data
{
[Serializable] <-- somehow we mark what we are going to write
double myValue;
...
[Serializable]
double myValueN;
}
public class LibraryInterop
{
IntPtr[] pointers; //Pointers that will go to SetAddressMethod
...
public void RegisterObject(Data data)
{
... //With reflection we look for [Serializable] values
//create a pointer for each and some kind of BindingInfo
//that knows connection of pointers[i] to data.myValueN
//Then add this pointers to C++ library
foreach(IntPtr pointer in pointers) { SetAddress(pointer);}
}
public void Flush()
{
//Loop through all added pointers
for(int i=0; i<pointers.Length; i++)
{
double value = ... //With reflections and BindingInfo we find data.myValueN
// that corresponds to pointers[i]
// then we write this value to memory of IntPtr
// we have to brake value to bytes and write it one by one to memory
// we could use BitConverter.DoubleToInt64Bits() but double - is just
// an example, so in general case we will use GetBytes
int offset = 0;
foreach(byte b in BitConverter.GetBytes(value))
{
Marshal.WriteByte(pointer[i],offset,byte);
offset++;
}
}
//Save values of IntPtr to disk
FlushValues();
}
}
Then the user code looks like this then
var library = new LibraryInterop();
var data1 = new Data();
var data2 = new AnotherData();
library.RegisterObject(data1);
library.RegisterObject(data2);
...//change data
library.Flush();
...//change data
library.Flush();
...//change data
library.Flush();
So in C++ we have a very neat structure. We have pointers, we fill data behind this pointers and on FlushValues all this values are writed.
C# part cannot have SetAddress(ref double value). Since address may change, we have to pin pointers - use unsafe+fixed or IntPtr, and have SO many headache.
On the other hand, we can have "managed pointers" by boxing|unboxing data.myValue to Object. So if it would be possible to somehow bind this ValueType data.myValue to IntPtr without this coping and reflection - it would be much much neater.
Is it possible to do this interop and have less ugly and slow C# part then the one I listed here?
(There are some major downsides to this...)
You can use GCHandle.Alloc(data1, GCHandleType.Pinned) to "pin" an object, and then get an IntPtr from GCHandle.AddrOfPinnedObject. If you do this, you'll be able to pass this IntPtr to your native code, which should work as expected.
However, this is going to cause a lot of issues in terms of undermining the efficiency of the garbage collector. If you decide to do something like this, I'd recommend allocating all of the objects very early on in your program (potentially immediately after calling a GC.Collect(), which is something I really don't normally recommend), and leaving them alone for the lifetime of your program. This would (slightly) mitigate the GC issues, as it'd allocate them into the "best" possible spot early on, and leave them where they'll only be touched in Gen2 collections.

Categories

Resources