Arduino Serial Communication from C# visual studio - c#

Arduino code
void setup() {
Serial.begin(9600);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BLUE_LED, OUTPUT);
Serial.write("x\n");
}
void loop() {
if(Serial.available() > 0){
if(first == true){ Serial.read(); first = false; }
if(Serial.peek() == 'r'){
analogWrite(RED_LED, (Serial.readString() + Serial.readString() + Serial.readString()).toInt());
}
else if(Serial.peek() == 'g'){
analogWrite(GREEN_LED, (Serial.readString() + Serial.readString() + Serial.readString()).toInt());
}
else if(Serial.peek() == 'b'){
analogWrite(BLUE_LED, (Serial.readString() + Serial.readString() + Serial.readString()).toInt());
Serial.write("x\n");
}
else{
error();
}
Serial.println(String(brightnessR) + "," + String(brightnessG) + "," + String(brightnessB) + "\n");
}
}
While simple there is an issue, probably due to my inability to understand the Serial methods. It begins with sending a test byte down the serial to tell the C# program on the computer that it can begin sending information. Next it checks if there are any bytes in the serial and if so it checks if the first byte matches any of the either r, g, or b and grabs the next three bytes from the serial and turns it into an integer.
On the visual studio side
string getRGB(Color rgb)
{
String rValue = "r";
if (type == 0)
{
if(rgb.R < 100)
{
rValue += "0";
}
if (rgb.R < 10)
{
rValue += "0";
}
type++;
return rValue + (rgb.R).ToString() + "\n";
}
String gValue = "g";
if (type == 1)
{
if (rgb.G < 100)
{
gValue += "0";
}
if (rgb.G < 10)
{
gValue += "0";
}
type++;
return gValue + (rgb.G).ToString() + "\n";
}
String bValue = "b";
if (type == 2)
{
if (rgb.B < 100)
{
bValue += "0";
}
if (rgb.B < 10)
{
bValue += "0";
}
type = 0;
return bValue + (rgb.B).ToString() + "\n";
}
return "";
}
public void SerializeRGB()
{
Color RGB = GetColorFromScreen(new Point(1160, 450));
if (LineOpen())
{
Updater(getRGB(RGB));
}
else
{
Values.Text = "Error\nError\nError";
}
}
public void Updater(String n)
{
Values.Text = n;
WriteSerial(n);
}
On visual studio if it detects that the arduino has requested data with the 'x' then it sends a string through the serial comprised of either r000 g000 b000 with the appropriate rgb values of the middle pixel on my screen.
The idea of this program is to translate screen colors onto a LED RGB strip hooked up to the Arduino. Currently the problem comes in that the program cannot identify whether there is an r,g or b at the beginning of the string and never gives a true for an if(){} statement and always end up on the else{}.
If anyone could help me solve this serial communication problem it would be very appreciated :)
Notes: Serial.readString() returns a string, Serial.read() returns the next byte in the serial.

I believe 10 is the char for a newline. Try filtering out for a new line/return. I would recommend set a string with a value of (String input = Serial.readString();), and using the first char from the string as you would be able to first filter the string of new lines/returns, which should give you the rgb chars.
String input = Serial.readString(); //gets string for serial port
input.trim(); //removes all whitespaces(\n\r, etc)
Char type = input.charAt(0); //gets first char

Related

How do I detect an infinite loop occuring in my code?

So my code is to check if a given number is a 'happy number'. It squares each digit of the number, adds them and continues to do so until either the result of the addition is 1 (which means it is a happy number) or until it results in a 4 (which means it is not a happy number).
What's happening is that there are many numbers which cause an infinite loop (therefore meaning they are not a happy number) and I'm wondering how I would construct my code so that it will detect when there's an infinite loop occuring? I have some ideas but all flawed.
My code is as follows:
using System;
namespace Happy_numbers_problem
{
class Program
{
static int HappyNumbers(string Number)
{
string Output = Number;
while ((Convert.ToInt32(Output) != 1) && (Convert.ToInt32(Output) != 4))
{
string Result2 = "0";
for (int Index = 0; Index < Output.Length; Index++)
{
string Character = Output.Substring(Index, 1);
int Calc = Convert.ToInt32(Character);
int Result = Calc * Calc;
//Adding Result2 and Result, then turning it into a string.
Result2 = Convert.ToString(Convert.ToInt32(Result2) + Result);
if (Index == (Output.Length) - 1)
{
Output = Result2;
}
}
}
return Convert.ToInt32(Output);
}
static void Main(string[] args)
{
Console.WriteLine("Please enter a number");
string Number = Console.ReadLine();
int Output = HappyNumbers(Number);
if (Output == 1)
{
Console.WriteLine(Number + " is a happy number");
}
else if (Output == 4)
{
Console.WriteLine(Number + " is not a happy number");
}
else
{
Console.WriteLine(Number + " is not a happy number");
}
}
}
}
The problem resides in your while condition. If your output needs to be 1 or 4 to break out of the loop and deliver the output to latter be analysed, you have to use the operator or || instead of the operator and &&.

C# code issue - Code not working properly

I wrote a basic number guessing game from C#. It seems to return the 3rd option ("Wrong choice! Please try again.") every time no matter what var c is chosen by the user. I was trying with characters (s instead of 1 and w instead of 2 etc with c as a string) but it gave the same results. Not sure where it's going bad.
using System;
namespace Challanges
{
class Program
{
static int guess = 500;
static int low = 1;
static int high = 1000;
static bool cont = false;
static void Guess() //guesses and adjusts variables according to input.
{
int c;
Console.WriteLine("Is your number greater or less than: " + guess + Environment.NewLine + "If it is less than, press 1; if it is greater, press 2." + Environment.NewLine + "If it is your number, press 3.");
c = Convert.ToInt32(Console.Read());
if (c == 1)
{
high = 500;
guess = low + high / 2;
}
else if (c == 2)
{
low = 500;
guess = low + high / 2;
}
else if (c == 3)
{
Console.WriteLine("Congratulations!! We found your number!");
cont = true;
}
else
{
Console.WriteLine("Wrong choice! Please try again.");
Console.ReadKey();
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!" + Environment.NewLine + "Let's play a guessing game. Think of a number between 1 and 1000." + Environment.NewLine + "Type your number :)");
int x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your number is: " + x + Environment.NewLine + "Too easy?");
Console.ReadKey();
Console.WriteLine("Think of a number");
if(cont == false)
{
Guess();
} else
{
Console.ReadKey();
}
}
}
}
As mentioned in the comments before, Console.Read() returns a character code. The character code for the number 1 is 49, thus your conditions fail and the else block is executed.
What you wanted to do was use Console.ReadLine()which returns a string instead of character codes. If you cast that string into an Int32 you should be able to evaluate your conditions correctly.

Increment Of Variable in another way in c# win. form

I am inventing an algorithm in which i have created a new number which is "z" (not actually z) and i am using it with the old numbers (0123456789) and my new series of number looks like this (0123456789z) but the problem here is that how to write a program that gives "19 + 1" as "z" and "z + 1" as "20".
Try something like this, though you'd have to implement additional coding for parameter checking and incrementing the second to last character if the last character reaches 0.
This is the basic logic:
private const string DIGITS = "0123456789z";
static void Main(string[] args)
{
Console.WriteLine(NextValue("9"));
Console.ReadKey();
}
private static string NextValue(string value)
{
char nextChar = '\0';
if(!string.IsNullOrEmpty(value))
{
char lastChar = value[value.Length - 1];
int nextCharIndex = DIGITS.IndexOf(lastChar) + 1;
if (nextCharIndex > DIGITS.Length)
nextChar = DIGITS[0];
else
nextChar = DIGITS[nextCharIndex];
}
return nextChar.ToString();
}
After you edited your question, I think what you're after is this
public int incrementNumber(string number)
{
var lastNumber = int.Parse(number.Last());
return (number.Length - 1) + ((lastNumber + 1) % 10).ToString();
}
% 10 or Mod 10 takes the reminder of the number divided by 10. So if you pass in 9 it will increment to 10 then wrap around to 0. When you pass in 5 it will increment to 6 and stay as 6 because it's not divisible by 10.
This may not be optimized but works if you allow +1 to increment.
public static string NextValue(string Counting)
{
int nextVal;
if(int.TryParse(Counting, out nextVal))
{
return (nextVal + 1).ToString();
}
else
{
char[] numbers = Counting.ToCharArray();
StringBuilder incremented = new StringBuilder();
foreach (char digit in numbers.Reverse())
{
if (digit == 'z')
{
incremented.Append("0");
}
else if (int.TryParse(digit.ToString(), out nextVal))
{
nextVal = nextVal + 1;
if (nextVal == 10)
{
incremented.Append("z");
}
else
{
incremented.Append(nextVal.ToString());
}
incremented.Append(string.Concat(numbers.Reverse().Skip(incremented.Length)));
break;
}
else
{
//Invalid character in number except for z
return string.Empty;
}
}
if (incremented[incremented.Length - 1] == '0')
incremented.Append("1");
return Reverse(incremented.ToString());
}
}
public static string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}

C# method for converting CSV to sparse data format for libsvm

I have developed a C# method for converting CSV to sparse data format. The code works nice but sometimes it fells. So, does anybody
have a C# method for converting CSV file to sparse file.
The format of sparse data is
[label] [column_index]:[value] [column_index]:[value] ...
[label] [column_index]:[value] [column_index]:[value] ...
One thing is that whenever a column value is 0 the column_index is jumped.
For example,
400,0.39,0,0.098,0.4387
421,0.63,0.23,0,0.14
represented as
400 1:0.39 3:0.098 4:0.4387
421 1:0.63 2:0.23 4:0.14
My C# code was:
public static string getSparse(string path)
{
string final_string = String.Empty;
string[] line = System.IO.File.ReadAllLines(path);
int count = 0, m = 0;
foreach (string ln in line)
{
string[] num = ln.Split(new char[] { ',' });
foreach (string n in num)
{
if (count == 0)
final_string += n + " ";
else
{
if (n == "0")
{
count++;
continue;
}
final_string += count + ":" + n + " ";
}
count++;
}
count = 0;
final_string += Environment.NewLine;
m++;
}
return final_string;
}

String literal recognition problem

I'm trying to recognize string literal by reading string per symbol.
Example of my scanner skeleton:
public sealed class Scanner
{
// some class inner implementations
/// <summary>
///
/// </summary>
/// <param name="Line"></param>
/// <param name="LineNumber"></param>
public void Run(String Line, Int32 LineNumber)
{
var ChPosition = default(Int32);
var ChCurrent = default(Char);
var Value = new StringBuilder();
while (default(Char) != Line.ElementAtOrDefault<Char>(ChPosition))
{
ChCurrent = Line.ElementAtOrDefault<Char>(ChPosition);
#region [Whitespace]
if (Char.IsWhiteSpace(ChCurrent))
{
ChPosition++;
}
#endregion
else
{
switch (ChCurrent)
{
#region [String Literal (")]
case '"':
{
// skipping " sign, include only string inner value
ChCurrent = Line.ElementAtOrDefault<Char>(++ChPosition);
// ...? Problematic place!!!
this.Tokens.Enqueue(new SharedEntities.Token
{
Class = SharedEntities.Token.TokenClass.StringLiteral,
Value = Value.ToString()
}
);
Value.Clear();
ChPosition++;
break;
}
#endregion
{
throw new ScanningException(
"<syntax_error#" + ChCurrent.ToString() + ">\n"
+ "Unsupported character appeared at: {ln: "
+ LineNumber.ToString()
+ "; pos: "
+ (ChPosition + 1).ToString()
+ "}"
);
}
} // [switch(ChCurrent)]
} // [if(Char.IsWhiteSpace(ChCurrent))...else]
} // [while(default(Char) != Line.ElementAtOrDefault<Char>(ChPosition))]
} // [public void Run(String Line, Int32 LineNumber)]
} // [public sealed class Scanner]
My target is to parse pascal-like string: "{everything enclosed, but ", only "" pair is allowed}".
First, you are obviously using some kind of parsing library, you would have better chance if you had modified your code, e.g. to something like I did, so that anybody can copy, paste, run your code.
Answer is simple, your (string literal)-parsing region does not parse all input. Here is your code modified to be used without any additional library:
public class Test
{
static char ElementAtOrDefault(string value, int position)
{
return position >= value.Length ? default(char) : value[position];
}
static string parseStringLiteral(string value, ref int ChPosition)
{
StringBuilder Value = new StringBuilder();
char ChCurrent = ElementAtOrDefault(value, ++ChPosition);
while (ChCurrent != '"')
{
Value.Append(ChCurrent);
ChCurrent = ElementAtOrDefault(value, ++ChPosition);
if (ChCurrent == '"')
{
// "" sequence only acceptable
if (ElementAtOrDefault(value, ChPosition + 1) == '"')
{
Value.Append(ChCurrent);
// skip 2nd double quote
ChPosition++;
// move position next
ChCurrent = ElementAtOrDefault(value, ++ChPosition);
}
}
else if (default(Char) == ChCurrent)
{
// message: unterminated string
throw new Exception("ScanningException");
}
}
ChPosition++;
return Value.ToString();
}
public static void test(string literal)
{
Console.WriteLine("testing literal with " + literal.Length +
" chars:\n" + literal);
try
{
int pos = 0;
string res = parseStringLiteral(literal, ref pos);
Console.WriteLine("Parsed " + res.Length + " chars:\n" + res);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
Console.WriteLine();
}
public static int Main(string[] args)
{
test(#"""Hello Language Design""");
test(#"""Is there any problems with the """"strings""""?""");
test(#"""v#:';?325;.<>,|+_)""(*&^%$##![]{}\|-_=""");
return 0;
}
}
Running this program produces output:
testing literal with 23 chars:
"Hello Language Design"
Parsed 21 chars:
Hello Language Design
testing literal with 45 chars:
"Is there any problems with the ""strings""?"
Parsed 41 chars:
Is there any problems with the "strings"?
testing literal with 39 chars:
"v#:';?325;.,|+_)"(*&^%$##![]{}\|-_="
Parsed 18 chars:
v#:';?325;.,|+_)
So it works for your testing, but algorithm is not correct, try running:
//literal with "", should produce ", but it does not
test(#"""""""""");
And you will incorrectly get:
testing literal with 4 chars:
""""
Parsed 0 chars:
Problem is, if you encounter character " in your while condition, you do not check next character, if it is " or not:
while (ChCurrent != '"') //bug
Of course, I created correct version for you :-)
Here it is (it uses your style, just edited version of yours):
static string parseStringLiteral(string value, ref int ChPosition)
{
StringBuilder Value = new StringBuilder();
char ChCurrent = ElementAtOrDefault(value, ++ChPosition);
bool goon = true;
while (goon)
{
if (ChCurrent == '"')
{
// "" sequence only acceptable
if (ElementAtOrDefault(value, ChPosition + 1) == '"')
{
Value.Append(ChCurrent);
// skip 2nd double quote
ChPosition++;
// move position next
ChCurrent = ElementAtOrDefault(value, ++ChPosition);
}
else goon = false; //break;
}
else if (default(Char) == ChCurrent)
{
// message: unterminated string
throw new Exception("ScanningException");
}
else
{
Value.Append(ChCurrent);
ChCurrent = ElementAtOrDefault(value, ++ChPosition);
}
}
ChPosition++;
return Value.ToString();
}
Happy coding :-)

Categories

Resources