Related
#include <Keypad.h>
#include <IRremote.h>
const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 4; //four columns
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
int A[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
int B[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
int C[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
int D[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
char keys[ROW_NUM][COLUMN_NUM] = {
{'1','2','3', 'A'},
{'4','5','6', 'B'},
{'7','8','9', 'C'},
{'*','0','#', 'D'}
};
byte pin_rows[ROW_NUM] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
void setup(){
Serial.begin(9600);
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop(){
char key = keypad.getKey();
if (key == "#"){
irsend.sendRC5(0x0, 8); //send 0x0 code (8 bits)
delay(200);
irsend.sendRC5(0x1, 8);
delay(200);
char array_choice = keypad.getKey();
if (array_choice == "A") {
int selected_array = A;
int index_of_signal = keypad.getKey();
if (index_of_signal == 0) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 1) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 2) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 3) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 4) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 5) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 6) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 7) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 8) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 9) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
}
if (array_choice == "B") {
int selected_array == B;
int index_of_signal = keypad.getKey();
if (index_of_signal == 0) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 1) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 2) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 3) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 4) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 5) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 6) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 7) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 8) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
if (index_of_signal == 9) {
irsend.sendRC5(selected_array[index_of_signal], 8);
}
}
}
if (key == "*") {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume();
}
}
}
This code is for a universal IR remote, it's supposed to get the value of the IR signal in the selected array and transmit the signal.
Yet when I try to get the keypad input to select the array the user would like to use, I get the error mentioned in the title. I know that my mistake is that the keypad is storing the selection as a char, because of that, it is unable to recognise that the input is supposed to select a specific array and access it. I heard that it might be impossible to get the variables with their stored arrays this way so if you have any ideas on how else to do it, please say so.
How would I go about fixing this problem? Any help would be appreciated.
Edit1: I tried substituting selected_array with the array itself such as:
if (index_of_signal == 1) {
irsend.sendRC5(A[index_of_signal], 8);
}
Yet the error I am getting now is error compiling for Arduino uno board, yet it doesn't point to a specific error in the code.
I like to sort an array with objects that have multiple properties. My objects have a string called name and a boolean called mandatory.
First i want to sort on age, next on the name.
How do I do this?
Ordering by age is easy...:
this.model.mylist.sort((obj1: IObj, obj2: IObj => {
if (obj1.age < obj2.age) {
return -1;
}
if (obj1.age > obj2.age) {
return 1;
}
return 0;
});
Well, you only add comparation for case when the two age values are the same. So something like this should work:
this.model.mylist.sort((obj1: IObj, obj2: IObj) => {
if (obj1.age < obj2.age) {
return -1;
}
if (obj1.age > obj2.age) {
return 1;
}
return obj1.name.localeCompare(obj2.name);
});
Something like this should work. The method compares the current and next values and adds comparison to the case when the two age values are the same. Then assume the column name in order based on age.
private compareTo(val1, val2, typeField) {
let result = 0;
if (typeField == "ftDate") {
result = val1 - val2;
} else {
if (val1 < val2) {
result = - 1;
} else if (val1 > val2) {
result = 1;
} else {
result = 0;
}
}
return result;
}
-
this.model.mylist.sort((a, b) => {
let cols = ["age", "name"];
let i = 0, result = 0, resultordem = 0;
while (result === 0 && i < cols.length) {
let col = cols[i];
let valcol1 = a[col];
let valcol2 = b[col];
let typeField = "string";
if (col == "age") {
typeField = "number";
}
if (valcol1 != "null" && valcol1 != "null") {
resultordem = this.compareTo(valcol1, valcol2, typeField);
if (resultordem != 0) {
break;
}
}
i++;
}
return resultordem;
});
This question already has answers here:
strcmp on a line read with fgets
(6 answers)
Closed 7 years ago.
#include <stdio.h>
#include <math.h>
#include <string.h>
#define size 7
int computeN(char s1[])
{
int n=-1;
if(strcmp(s1, "black") == 0)
{
n = 0;
}
else if (strcmp(s1, "brown") == 0)
{
n = 10;
}
else if (strcmp(s1, "red") == 0)
{
n = 20;
}
else if (strcmp(s1, "orange") == 0)
{
n = 30;
}
else if (strcmp(s1, "yellow") == 0)
{
n = 40;
}
else if (strcmp(s1, "green") == 0)
{
n = 50;
}
else if (strcmp(s1, "blue") == 0)
{
n = 60;
}
else if (strcmp(s1, "violet") == 0)
{
n = 70;
}
else if (strcmp(s1, "grey") == 0)
{
n = 80;
}
else if (strcmp(s1, "white") == 0)
{
n = 90;
}
printf("%d\n", n);
return n;
}
int computeN2(char s2[])
{
int n1=-1;
if(strcmp(s2, "black") == 0)
{
n1 = 0;
}
else if (strcmp(s2, "brown") == 0)
{
n1 = 1;
}
else if (strcmp(s2, "red") == 0)
{
n1 = 2;
}
else if (strcmp(s2, "orange") == 0)
{
n1= 3;
}
else if (strcmp(s2, "yellow") == 0)
{
n1 = 4;
}
else if (strcmp(s2, "green") == 0)
{
n1 = 5;
}
else if (strcmp(s2, "blue") == 0)
{
n1 = 6;
}
else if (strcmp(s2, "violet") == 0)
{
n1 = 7;
}
else if (strcmp(s2, "grey") == 0)
{
n1 = 8;
}
else if (strcmp(s2, "white") == 0)
{
n1 = 9;
}
printf("%d\n", n1);
return n1;
}
int computeExponent(char s3[])
{
int exp=0;
if(strcmp(s3, "black") == 0)
{
exp = 1;
}
else if (strcmp(s3, "brown") == 0)
{
exp = 10;
}
else if (strcmp(s3, "red") == 0)
{
exp = 100;
}
else if (strcmp(s3, "orange") == 0)
{
exp = 1000;
}
else if (strcmp(s3, "yellow") == 0)
{
exp = 10000;
}
else if (strcmp(s3, "green") == 0)
{
exp = 100000;
}
else if (strcmp(s3, "blue") == 0)
{
exp = 1000000;
}
else if (strcmp(s3, "violet") == 0)
{
exp = 10000000;
}
else if (strcmp(s3, "gray") == 0)
{
exp = 100000000;
}
else if (strcmp(s3, "white") == 0)
{
exp = 1000000000;
}
printf("%d\n", exp);
return exp;
}
int computeResistance(int x, int y, int z)
{
int omega = ((x+y) * z);
return omega;
}
int main(void)
{
char color_codes[10][7] = {"black","brown","red","orange","yellow","green","blue","violet","gray","white"};
char s1[7], s2[7], s3[7];
int n, n1, choice;
printf("Enter the colors of the resistor's three bands, beginning with\n");
printf("the band nearest the end. Type the colors in lowercase letters\n");
printf("only, NO CAPS\n");
printf("Band 1 =>\n"); //prints prompts for bands
fgets(s1, size, stdin); //stores band 1 in s1
printf("Band 2 => \n"); //prints prompt
fgets(s2, size, stdin); //stores band 2 in s2
printf("Band 3 => \n"); //prints prompt
fgets(s3, size, stdin); //stores band 3 in s3
printf("Resistance value: %d\n", computeResistance(computeN(s1), computeN2(s2), computeExponent(s3))); //computes resistance
return (0); //make the exit
}
The strings are being stored properly; the issue is the fact that within the functions the correct value is not being found within the comparison in order to find the resistance with the algorithm. If the user enters 'red', 'red', 'red', the values n,n1, and exp will be equal to -1,-1,0. What could be causing this?
The problem here is, fgets() scans and stores the trailing newline, too, into the input buffer.
You need to get rid of that newline before sending the input for comparison. Otherwise, your string comparison is pretty much likely to fail.
A very simple solution can be like, check the string length of the input, then check on the last index value against the newline (\n), if you found that, replace that with null (\0) and then, pass on the input to the comparison function(s).
fgets includes the newline character in the string it reads. You'll either have to remove it or use a function like scanf which does not include the newline. (If you use scanf, remember to use e.g. %7s specifiers to prevent buffer overflows).
struct node* tempA;
struct node* tempB;
n = 501;
m = 501;
tempA = A;
tempB = B;
while ( tempA != NULL && tempB != NULL )
{
if ( tempA->data == tempB->data )
{
int common = tempA->data;
if (fastintersect(common+n,block,closed_area)||fastintersect(common-n,block,closed_area)||(fastintersect(common-1,block,closed_area) && common%n != 1)||(fastintersect(common+1,block,closed_area) && common%n != 0 ))
{
AppendNode(&C,common);
tempA = tempA->next;
tempB = tempB->next;
if( search(A,common) != length(A) )
{
DeleteNode(&A,common);
}
else
{
DeleteEndNode(A);
}
if( search(B,common) != length(B) )
{
DeleteNode(&B,common);
}
else
{
DeleteEndNode(B);
}
}
else
{
tempA = tempA->next ;
tempB = tempB->next ;
}
}
else if ( tempA->data > tempB->data )
tempB = tempB->next;
else
tempA = tempA->next;
}
// The fastintersect function
int fastintersect(int x,int arr[],int sizearr)
{
int found = 0;
int lower = 0;
int upper = sizearr - 1 ;int i=0;
if( (x == arr[lower]) || (x == arr[upper]) )
{
found = 1;
}
else if ( x > arr[lower] && x < arr[upper])
{
while ( lower <= upper )
{
int middle = ( lower + upper ) / 2;
if ( x > arr[middle])
{ lower = middle +1 ;}
else if (x < arr[middle])
{upper = middle - 1;}
else
{ found = 1;break;}
}
}
return found;
}
This is a function to delete the common elements of 2 sorted linked lists A and B . When there are common elements the fastintersect criterion is checked and corresponding elements are deleted and new linked list C is generated whose elements are the ones which satisfy the common elements criteria as well as the fastintersect check .Block is just a matrix which has some values against which the common is checked and if present will return a value 1 else 0. Am I doing the deleting correctly ? Is this a valid code ?
In a 3D scene, I have an Object that has a position that I would like to move using Lua.
eg. box.position.x = 10
box has a metatable ("Object") and so has position ("Vec"). Object has __newindex and __index set to call C functions NewIndexObject and IndexObject respectively. Same with Vec (NewIndexVec and IndexVec).
Object has an id so it can be identified in a list that is stored in the scene and when box.position is accessed all is fine, the C function IndexObject is called and I can extract the id from the stack, it's just when box.position.x = 10 is executed 'NewIndexVec' is called and the only thing on the stack is {table, x, 10} so no way of identifying the object to change its x position.
Is there anyway of pushing values onto a local state? Help!
UPDATE: thank you for getting back to me quickly, below I have distilled the code as much as possible. If you run this code it'll appear to work but I have comments where I'm stuck, it's just getting the first object in the array but I need to choose it by it's ID, Thanks in advance
struct Obj
{
std::string id;
int x,y,z;
Obj()
{
x = 10; y = 20; z = 30;
id = "12345";
}
};
//array of external objects
std::vector<Obj> objects;
int NewObject(lua_State * L)
{
Obj obj;
objects.push_back(obj);
lua_newtable(L);
luaL_getmetatable(L, "MT_Object");
lua_setmetatable(L, -2);
lua_pushstring(L, "id");
lua_pushstring(L, obj.id.c_str());
lua_settable(L, 1);
lua_newtable(L);
luaL_getmetatable(L, "MT_Vec");
lua_setmetatable(L, -2);
lua_pushinteger(L, obj.x);
lua_setfield(L, -2, "x");
lua_pushinteger(L, obj.y);
lua_setfield(L, -2, "y");
lua_pushinteger(L, obj.z);
lua_setfield(L, -2, "z");
lua_setfield(L, -2, "position");
return 1;
}
int IndexVec(lua_State * L)
{
// How do I get the correct object so I can pass its value back
Obj &dunnoObj = objects[0];
std::string key = luaL_checkstring(L,-1);
if(key == "x")
lua_pushinteger(L,dunnoObj.x);
else if(key == "y")
lua_pushinteger(L,dunnoObj.y);
else if(key == "z")
lua_pushinteger(L,dunnoObj.z);
return 1;
}
int NewIndexVec(lua_State * L)
{
// How do I know which object's value to update
Obj &dunnoObj = objects[0];
std::string key = luaL_checkstring(L,-2);
int value = luaL_checkinteger(L,-1);
if(key == "x")
dunnoObj.x = value;
else if(key == "y")
dunnoObj.y = value;
else if(key == "z")
dunnoObj.z = value;
return 0;
}
int main()
{
lua_State * L = luaL_newstate();
luaL_openlibs(L);
luaL_Reg objreg[] =
{
{ "new", NewObject },
{ NULL, NULL }
};
luaL_newmetatable(L, "MT_Object");
luaL_register(L, 0, objreg);
lua_setglobal(L, "Object");
luaL_Reg reg[] =
{
{ "__index", IndexVec },
{ "__newindex", NewIndexVec },
{ NULL, NULL }
};
luaL_newmetatable(L, "MT_Vec");
luaL_register(L, 0, reg);
lua_setglobal(L, "Vec");
int res = luaL_dostring(L, "box = Object.new() box.position.x = 1000 print(box.id .. \" , \" ..box.position.x .. \" , \" .. box.position.y .. \" , \" .. box.position.z)");
if(res)
printf("Error: %s\n", lua_tostring(L, -1));
lua_close(L);
return 0;
}
If I understand you correctly, you don't have to do anything. Tables are tracked by reference, so NewIndexVec doesn't need to know anything about box if its first argument is box.position.
If this answer can't work for some reason, then I'd need more information about your data structure to understand your problem.
Basically, box.position needs to return some obj for which obj.x = 10 is a valid operation and changes exactly what you want it to change.
The problem is that you're trying to keep the same data in two separate places. Keep all the data in the C++ struct, then have NewObject return a userdata that pretends to be a table. Both the Object and the position field should be the same Obj*, but they may have different metatables to simulate different sets of fields.
Thanks, I've posted the code that works
struct Obj
{
unsigned int id;
int x,y,z;
Obj()
{
x = 10; y = 20; z = 30;
id = rand();
}
};
//array of external objects
std::map<unsigned int,Obj> objects;
int NewObject(lua_State * L)
{
Obj obj;
objects[obj.id] = obj;
lua_pushinteger(L, obj.id);
luaL_getmetatable(L, "MT_Object");
lua_setmetatable(L, -2);
return 1;
}
int IndexObj(lua_State * L)
{
unsigned int objid = luaL_checkinteger(L,1);
std::string key = luaL_checkstring(L,-1);
if(key == "position" )
{
Obj *a = (Obj *)lua_newuserdata(L, sizeof(Obj));
*a = objects[objid];
luaL_getmetatable(L, "MT_Vec");
lua_setmetatable(L, -2);
}
else if(key == "id")
lua_pushinteger(L, objid);
else
lua_pushnil(L);
StackDump(L);
return 1;
}
int IndexVec(lua_State * L)
{
Obj *a = (Obj *)lua_touserdata(L, 1);
std::string key = luaL_checkstring(L,-1);
if(key == "x")
lua_pushinteger(L,a->x);
else if(key == "y")
lua_pushinteger(L,a->y);
else if(key == "z")
lua_pushinteger(L,a->z);
return 1;
}
int NewIndexVec(lua_State * L)
{
Obj *a = (Obj *)lua_touserdata(L, 1);
Obj &objRef = objects[a->id];
std::string key = luaL_checkstring(L,-2);
int value = luaL_checkinteger(L,-1);
if(key == "x")
objRef.x = value;
else if(key == "y")
objRef.y = value;
else if(key == "z")
objRef.z = value;
return 0;
}
int main()
{
lua_State * L = luaL_newstate();
luaL_openlibs(L);
luaL_Reg objreg[] =
{
{ "new", NewObject },
{ "__index", IndexObj },
{ "__newindex", NewIndexObj },
{ NULL, NULL }
};
luaL_newmetatable(L, "MT_Object");
luaL_register(L, 0, objreg);
lua_setglobal(L, "Object");
luaL_Reg reg[] =
{
{ "__index", IndexVec },
{ "__newindex", NewIndexVec },
{ NULL, NULL }
};
luaL_newmetatable(L, "MT_Vec");
luaL_register(L, 0, reg);
lua_setglobal(L, "Vec");
int res = luaL_dostring(L, "box = Object.new() box.position.x = 1000 "
"print(box.id .. \" , \" ..box.position.x .. \" , \" .. box.position.y .. \" , \" .. box.position.z)");
if(res)
printf("Error: %s\n", lua_tostring(L, -1));
lua_close(L);
return 0;
}