How to change value in array and convert to RGB - c

I am making a project where RFID tags on 6 RFID readers will create a 6-digit HEX-code which will be converted and output through RGB.
I am converting HEX values to RGB values and print the values in serial, which works fine. E.g when I write #FFFFFF, Serial prints its respective RGB values - 255, 255, 255.
However, I want to be able to replace one of the letters in the HEX code at a time, which should change its RGB output in serial. In this example, I am attempting to replace the last letter of #FFFFFF to 3 - #FFFFF3. Serial still reads the first two values correctly, but does not convert the last value correctly.
I have read that it is better to create a new array with the new value -
instead of replacing a value and changing the array but do not really know how. Here's what I have got now:
#include <stdlib.h>
#include <string.h>
void setup() {
Serial.begin(9600);
}
char hexColor[] = "#FFFFFF";
void HEXtoRGB();
void HEXtoRGB() {
hexColor[6] = "3";
char red[5] = {0};
char green[5] = {0};
char blue[5] = {0};
red[0] = green[0] = blue[0] = '0';
red[1] = green[1] = blue[1] = 'X';
red[2] = hexColor[1];
red[3] = hexColor[2];
green[2] = hexColor[3];
green[3] = hexColor[4];
blue[2] = hexColor[5];
blue[3] = hexColor[6];
long r = strtol(red, NULL, 16);
long g = strtol(green, NULL, 16);
long b = strtol(blue, NULL, 16);
Serial.println(r);
Serial.println(g);
Serial.println(b);
Serial.println(hexColor);
}
Any sort of input would be greatly appreciated, it's the first time writing in something else than javascript.
Thank you.

The main error you're doing is confusing "3" with '3'.
"3" is a string which in C is a null-terminated array of chars while '3' is the character 3. So
hexColor[6] = "3"; means: "write the memory address of the string "3" into hexColor[6]".
What you wanted to do is:
hexColor[6] = '3';

This should work:
char hexColor[7] = "#FFFFFF";
int main(){
for(int i=0; i<7; i++)
printf("%c ", hexColor[i]);
hexColor[6]='3';
for(int i=0; i<7; i++)
printf("%c ", hexColor[i]);
}
Outout:
#FFFFFF #FFFFF3

Related

How do I add a 2 Digit number inside an Array as a single entry using getch()?

I've got this example which I made but it doesn't work.
This code is supposed to add XX:YY:ZZ to an array that has 3 columns: realtime = {XX, YY, ZZ}
#include <stdio.h>
#include <conio.h>
int main() {
int realtime[3];
char time[8];
for(int i = 0;i<8;i++){
time[i] = getche();
}
for(int i = 0, j = 0;i<3;i++, j+=3){
realtime[i] = (time[j])*10+time[j+1];
}
}
Notice that the character '0' does not have the integer value 0. See for instance https://en.wikipedia.org/wiki/ASCII
The integer value of the character '0' is normally 48. So if you read the text string "01:23:45", you'll end up with time[0] having the integer value 48, time[1] having the integer value 49, time[3] having the integer value 50 and so on.
Therefore you need to subtract 48 to the values in time in the second loop. That is normally done by: time[j]-'0'.
Try this:
for(int i = 0, j = 0;i<3;i++, j+=3){
realtime[i] = ((time[j]-'0')*10+(time[j+1]-'0');
// ^^^^ ^^^^^
}

How to convert byte to int?

I have an Arduino which is reading in a set of three bytes from a program which correspond to degrees in which an actuator must turn. I need to convert these bytes into integers so I can pass those integers on to my actuators.
For example, I know the default rest state value I receive from the program is 127. I wrote a C# program to interpret these bytes and that can get them to a single integer value. However, I am unable to figure out how to do this in the Arduino environment with C. I have tried typecasting each byte to a char and storing that in a string. However that returns garbled values that make no sense.
void loop() {
if(Serial.available() && sw)
{
for(int j = 0; j < 3; j++)
{
input[j] = Serial.read();
}
//command = ((String)input).toInt();
sw = 0;
}
String myString = String((char *)input);
Serial.println(myString);
}
The return value of Serial.read() is an int. Therefore, if you have the following code snippet:
int input[3];
for (int i = 0; i < 3; i++) {
input[i] = Serial.read();
}
Then input should store three ints. However, the code:
char* input[3];
for (int i = 0; i < 3; i++) {
input[i] = Serial.read();
}
Will just store the byte conversion from int to char.
If you want to store this as a string, you need to do a proper conversion. In this case, use itoa (see Arduino API description).
The code snippet would be:
#include <stdlib>
char* convertedString = itoa(input[i]);
This should work:
int command = input[0]*256*256 + input[1]*256 + input[2];
By the way the default language you use to program your an Arduino is C++, not C. Although they have some similarities.
Below logic will help you
iDst = (cSrc[0] << 16) | (cSrc[1] << 8) | cSrc[2]
or else you can use union for this case
union byte2char
{
char c[4];
int i;
};
But union implementation needs to consider little and big endian systems

How to use strncpy with a for-loop in C?

I am writing a program which will take every 3 numbers in a file and convert them to their ASCII symbol. So I thought I could read the numbers into a character array, and then make every 3 elements 1 element in a second array, convert them to int and then print these as char.
I am stuck on taking every 3 elements, however. This is my code snippet for this part:
char arry[] = "073102109109112"; <--example string read from a file
char arryNew[16] = {0};
for(int i = 0; i <= sizeof(arryNew); i++){
strncpy(arryNew, arry, 3);
arryNew[i+3]='\0';
puts(arryNew);
}
What this code gives me is the first 3 numbers, fifteen times. I've tried incrementing i by 3, which gives me the first 3 numbers 5 times. How do I write a for-loop with strncpy so that after copying n chars, it moves to the next n chars?
You pass always the pointer to the beginning of the array, so you will always have the same result of course. You must include the loop counter to get at the next block:
strncpy(arryNew, &arry[i*3], 3);
Here you have a problem:
arryNew[i+3]='\0';
First of all, you don't need to set the null byte every time, because this will not change anyway. Additionally you will corrupt memory, because you use i+3 as the index so when you reach 14 and 15, it will write beyond the arrayboundary.
Your arrayNew must be longer, because your original array is 16 characters, and your target array is also. If you intend to have several 3char strings in there, then you must have 5*4 characters for your target, because each string also has the 0-byte.
And of course, you must also use the index here as well. The way it is written now, it will write beyond the array boundary, when i reaches 14 and 15.
So what you seem to want to do (not sure from your description) is:
char arry[] = "073102109109112"; <--example string read from a file
char arryNew[20] = {0};
for(int i = 0; i <= sizeof(arry); i++)
{
strncpy(&arryNew[i*4], &arry[i*3], 3);
puts(&arryNew[i*4]);
}
Or if you just want to have the individual strings printed then you can just do:
char arry[] = "073102109109112"; <--example string read from a file
char arryNew[4] = {0};
for(int i = 0; i <= sizeof(arry); i++)
{
strncpy(arryNew, &arry[i*3], 3);
puts(arryNew);
}
Making things a bit simpler: your target string doesn't change.
char arry[] = "073102109109112"; <--example string read from a file
char target[4] = {0};
for(int i = 0; i < strlen(arry) - 3; i+=3)
{
strncpy(target, arry + i, 3);
puts(target);
}
Decoding:
start at the beginning of arry
copy 3 characters to target
(note the fourth element of target is \0)
print out the contents of target
increment i by 3
repeat until you fall off the end of the string.
Some problems.
// Need to change a 3 chars, as text, into an integer.
arryNew[i] = (char) strtol(buf, &endptr, 10);
// char arryNew[16] = {0};
// Overly large.
arryNew[6]
// for(int i = 0; i <= sizeof(arryNew); i++){
// Indexing too far. Should be `i <= (sizeof(arryNew) - 2)` or ...
for (i=0; i<arryNewLen; i++) {
// strncpy(arryNew, arry, 3);
// strncpy() can be used, but we know the length of source and destination,
// simpler to use memcpy()
// strncpy(buf, a, sizeof buf - 1);
memcpy(buf, arry, N);
// arryNew[i+3]='\0';
// Toward the loop's end, code is writing outside arryNew.
// Lets append the `\0` after the for() loop.
// int i
size_t i; // Better to use size_t (or ssize_t) for array index.
Suggestion:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char Source[] = "073102109109112"; // example string read from a file
const int TIW = 3; // textual integer width
// Avoid sprinkling bare constants about code. Define in 1 place instead.
const char *arry = Source;
size_t arryLen = strlen(arry);
if (arryLen%TIW != 0) return -1; // is it a strange sized arry?
size_t arryNewLen = arryLen/TIW;
char arryNew[arryNewLen + 1];
size_t i;
for (i=0; i<arryNewLen; i++) {
char buf[TIW + 1];
// strncpy(buf, a, sizeof buf - 1);
memcpy(buf, arry, TIW);
buf[TIW] = '\0';
char *endptr; // Useful should OP want to do error checking
// TBD: test if result is 0 to 255
arryNew[i] = (char) strtol(buf, &endptr, 10);
arry += TIW;
}
arryNew[i] = '\0';
puts(arryNew); // prints Ifmmp
return 0;
}
You could use this code to complete your task i.e. to convert the given char array in form of ascii value.
char arry[] = "073102109109112";
char arryNew[16] = {0};
int i,j=0;
for(i = 0; i <= sizeof(arryNew)-2; i+=3)
{
arryNew[j]=arry[i]*100+arry[i+1]*10+arry[i+2]*1;
j++;
arryNew[j+1]='\0';
puts(arryNew);
}

Converting a char to an int for int arithmetic in java

i have a bit of strange confusion happening when trying to convert my char variables from my char array into ints.
Here is my code:
public class Luhn {
private String cardNumber;
private char[] cardArray;
public Luhn(String cardNumber) {
this.cardNumber = cardNumber;
cardArray = new char[cardNumber.length()];
for (int i = 0; i < cardNumber.length(); i++) {
cardArray[i] = cardNumber.charAt(i);
}
public void calculation() {
for(int i = cardArray.length-1; i >= 0; i-=2) {
char y = cardArray[i];
int x = (int) (cardArray[i] * 1);
if(x > 9) {
//int total = 0;
}
}
}
I keep getting strange outputs in x. Something like 58. I'm accessing the array backwards and retrieving every 2nd number back to the front of the array. I basically want x to be whatever the number is in each array element. I know with this small piece of code it will overwrite x continuously, but i want it to be the number designated in the char array, not some random number not matching my array elements. The problem is in the calculation method where i try and convert the char to int.
Please help
Thanks.
For Example;
You can do
(int)(cardArray[i] - '0')
to convert a single digit to a number.
The reason you can do this is because each char is a number.
'0' = 48
'1' = 49
'2' = 50
'3' = 51
...
'9' = 57
Subtraction the value for 0 gets you the integer value for each of the characters.
chars are actually numbers that represent chars. if you want to convert it into an int, subtract the 0 char
int x = (int) (cardArray[i] - '0');
You could use Character.getNumericValue(char), See JavaDoc here

Concat LPSTR in C

Trying to use as basic C as I can to build a list of numbers from 1-52 in a random order (deck of cards). Everything works, but all of my attempts to concat the strings and get a result end in failure. Any suggestions? NOTE: This is not homework it's something I'm using to create a game.
// Locals
char result[200] = ""; // Result
int card[52]; // Array of cards
srand(time(0)); // Initialize seed "randomly"
// Build
for (int i=0; i<52; i++) {
card[i] = i; // fill the array in order
}
// Shuffle cards
for (int i=0; i<(52-1); i++) {
int r = i + (rand() % (52-i));
int temp = card[i]; card[i] = card[r]; card[r] = temp;
}
// Build result
for (int c=0; c<52; c++) {
// Build
sprintf(result, "%s%d", result, card[c]);
// Comma?
if ( c < 51 )
{
sprintf(result, "%s%s", result, ",");
}
}
My end result is always garbled text. Thanks for the help.
You keep writing to the same position of "result".
sprintf is not going to do the appending for you.
You may consider, after each sprintf, get the return value (which is the number of char written), and increment the pointer to result buffer. i.e. something like:
(psuedo code):
char result[200];
char * outputPtr = result;
for (int c=0; c<52; c++) {
// Build
int n = sprintf(outputPtr, "%d%s", card[c], (c<51 ? "," : ""));
outputPtr += n;
}
Are we writing C++ or C? In C++, concat-ing a string is just:
string_out = string_a + string_b
…since you'd be using std::string.
Furthermore, if this is C++, the STL has a std::shuffle function.
If this is C, note that all your sprintfs aren't concatenating strings, they're just overwriting the old value.
I think, if memory serves, that sprintf will always write into the buffer starting at byte 0. This means that you would be writing the first couple of bytes over and over again with a number, then a comma, then a number. Check if your first bytes are ",[0-9]" - if so, that's your issue.
This would add a comma between each number in the result string:
// Get a pointer to the result string
char* ptr = &result[0];
for (int c = 0; c < 52; c++) {
// Add each cards number and increment the pointer to next position
ptr += sprintf(ptr, "%d", card[c]);
// Add a separator between each number
if (c < 51) {
*ptr++ = ',';
}
}
// Make sure the result string is null-terminated
*ptr = 0;

Resources