Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Don't know why I'm getting this.
The program is a badly coded whack a mole game made to run on a Arduino Uno.
My IED is Arduino IED version 1.6.12
Yes, there's a lot more to it but chose to leave it out, if you want to see all the code just ask.
Error
Arduino: 1.6.12 (Windows 7), Board: "Arduino/Genuino Uno"
C:\Users\Strings\Documents\Arduino\Too_Many_Moles\Too_Many_Moles.ino: In function 'void winOrLost()':
Too_Many_Moles:146: error: invalid use of void expression
timelyCall(current_millis, toggleBuzer(), 1000);
^
C:\Users\Strings\Documents\Arduino\Too_Many_Moles\Too_Many_Moles.ino: In function 'void loop()':
Too_Many_Moles:191: error: invalid use of void expression
timelyCall(current_millis, popAMole(), time_interval);
^
exit status 1
invalid use of void expression
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Main.ino
const int buzer = A0, on_off_pin = A1;
unsigned long current_millis;
const int time_interval = 20;
int currentMole = 0;
int points = 0, lives = 3, level = 0, odds_of_pop_up = 6;
mole moles[6] = {
mole( 2, 8 ),
mole( 3, 9 ),
mole( 4, 10 ),
mole( 5, 11 ),
mole( 6, 12 ),
mole( 7, 13 )
};
int number_of_mole = sizeof(moles) / sizeof(*moles);
void timelyCall(unsigned long currentMillis, void (&f)(), int ms) {
if (millis() - currentMillis > ms) {
f();
currentMillis = millis();
}
}
void popAMole() {
if (moles[currentMole].isReadyToPop()) {
moles[currentMole].popUp(odds_of_pop_up);
}
if (currentMole + 1 <= number_of_mole) {
currentMole = 0;
}
else {
currentMole++;
}
}
mole.h
#ifndef mole_h
#define mole_h
#include "Arduino.h"
class mole
{
public:
mole(int p_out, int p_in);
void resetMole();
void popUp(int odds);
boolean moleGetHit();
boolean isReadyToPop();
void setUpTimer(int up_timer);
int getUpTimer();
void decrementUpTimer();
void setRecoveryTimer(int recovery_timer);
int getRecoveryTimer();
void decrementRecoveryTimer();
void addRecoveryTimer(int add_time);
boolean getSouldBeUp();
int getOddsOfPopinh();
void setOddsOfPopinh(int odds);
int getPinIn();
private:
boolean _sould_be_up = false;
int _up_timer = 0;
int _recovery_timer = 0;
int _pin_out;
int _pin_in;
int _odds_of_poping = 10;
};
#endif
mole.cpp
boolean mole::isReadyToPop() {
if (_recovery_timer == 0 && _sould_be_up = false) {
return true;
}
else {
return false;
}
}
void mole::popUp(int odds) {
if (rand() % odds + 1 == 1) {
digitalWrite(_pin_out, HIGH)
_sould_be_up = true;
}
}
You are calling the functions not passing the addresses to timelyCall!
timelyCall(current_millis, popAMole(), time_interval);
timelyCall(current_millis, toggleBuzer(), 1000);
Should be:
timelyCall(current_millis, popAMole, time_interval);
timelyCall(current_millis, toggleBuzer, 1000);
Notice no brackets on popAMole & toggleBuzer.
Related
Given a sequence of integers and a number, the program must say if there's any cobination in that sequence that sums the number. For example:
Input: 1 2 3 4 5 # 6
Output: true (because 1+5 = 6, or 2 + 4 = 6, or 1 + 2 + 3 = 6).
It doesn't matter what solution it finds, only if there's a solution.
For input: 1 2 3 4 5 # 100
Output: false. None of the combination of that numbers sums 100.
Now, for input:
243 5 35 24 412 325 346 24 243 432 # 1000
I'm getting
main: malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
When it's suppose to say false.
I must use 3 classes. Solver, solution and candidat.
Solver just calls the backtracking method.
Solution has a possible solution.
Candidat has the indeix of the number of the sequence which is being looked.
I don't understand how to use the integer _lvl of Solution class to move around the different candidates.
Class Solver is correct. The error must be in solution class and candidats.
My question is, how must I use candidats and _lvl to check the possible solutions?
How should I implement the following methods in solution class?:
Acceptable, complet, anotate, desanotate.
Im getting wrong answers and out_of_ranges errors.
class solver
{
public:
solver();
bool solve(const solution &initial);
solucio getSolution() const;
private:
void findASolution();
bool _found;
solution _sol;
};
solver.cpp
bool solver::solve(const solution &initial)
{
_found = false;
_sol = initial;
findASolution();
return (_found);
}
void solver::findASolution()
{
candidat iCan = _sol.inicializateCandidats();
while ((not iCan.isEnd()) and (!_found))
{
if (_sol.acceptable(iCan)) {
_sol.anotate(iCan);
if(not _sol.complet()) {
findASolution();
if (!_found) {
_sol.desanotate(iCan);
}
}
else {
_found = true;
}
}
iCan.next();
}
}
This class is supposed to be correct. Im having trouble with classes solution and candidat. Class solution have 5 important methods: Acceptable, Complet, inicializateCandidates(), anotate and desanotate.
Acceptable is true if a candidate can be part of the solution.
Complet if a solution is found.
Anotate to save the possible candidates.
Desanotate to remove candidates that no long can be part of the solution.
inicializateCandidates invoces the candidats constructor.
solution();
solution(const int sequence[], const int &n, const int &sum) {
_searchedSum = sum;
_n = n;
_sum = 0;
_lvl = 0;
reserve(); // bad_alloc. Makes space for vectors
for (int i = 0; i < n; i++) {
_sequence[i] = sequence[i];
_candidates[i] = - 1;
}
solution(const solution &o);
~solution();
solution & operator=(const solution &o);
candidat inicializateCandidats() const {
return candidat(_n);
}
bool acceptable(const candidat &iCan) const {
return (_sum + _sequence[iCan.actual()] <= _searchedSum);
}
bool complet() const {
return (_sum == _searchedSum);
}
void show() const;
void anotate(const candidat &iCan) {
_niv++;
_candidates[_niv] = iCan.actual();
_sum += _sequence[iCan.actual()];
}
void desanotate(const candidat &iCan) {
_candidates[_niv] = - 1;
_sum -= _sequence[iCan.actual()];
_niv--;
}
private:
// memory gestion methods
void solution::reserve() {
_sequence = new int[_n];
_candidates = new int[_n];
}
int *_sequence; // original sequence
int *_candidates; // possible subsequence part of solution
int _n; // size of the array
int _lvl; // lvl of the tree generated by backtracking
int _searchedSum;
int _sum; // total sum of actual solution
And class candidat, which is just a counter. Nothing else.
candidat::candidat(const int &n) {
_size = n;
_iCan = 0;
}
bool candidat::isEnd() const {
return (_iCan >= _size);
}
int candidat::actual() const {
if (esEnd()) {
throw ("No more candidates");
}
return _iCan;
}
void candidat::next() {
if (esFi()) {
throw ("No more candidates");
}
_iCan++;
}
I've found a possible solution but it does not fit the requirements at all.
In class solver, I create an attribute to save anterior candidate, inicializate at -1.
The constructor of candidat class changes at this way:
candidat::candidat(const int &n, const int &ant) {
_size = n;
_iCan = ant + 1;
}
In solution.h now there is a boolean array to save the candidates that can be part of the solution. _lvl is eliminated.
In solver.cpp, the backtracking changes a little, but it shouldn't be changed.
bool solver::solve(const solution &initial) {
_found = false;
_ant = -1;
_sol = initial;
findASolution();
return (_found);
}
void solver::findASolution() {
**candidat iCan = _sol.inicializateCandidats(_ant);**
while ((not iCan.isEnd()) and (!_found))
{
if (_sol.acceptable(iCan)) {
_sol.anotate(iCan);
if(not _sol.complet()) {
**_ant = iCan.actual();**
findASolution();
if (!_found) {
_sol.desanotate(iCan);
}
}
else {
_found = true;
}
}
iCan.next();
}
}
Differences remarked.
But this is not the best solution. The correct solution should be using _lvl attribute. The solver class shouldn't know aything about the attributes of solution. Just if it's found or not.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
While trying to filter the MainMenu array
const byte menuLength = 10;
struct Menu {
int id;
char Description[16];
int parentId;
};
Menu MainMenu[menuLength] = {
{ 1, "SYSTEM SETUP ", -1 },
{ 2, "FUNCTIONS SETUP", -1 },
{ 3, "FIRMWARE VER. ", -1 },
//SYSTEM SETUP
{ 4, "< BACK ", 1 },
{ 5, "MODEL SELECT ", 1 },
{ 6, "RX SETUP ", 1 },
//FUNCTIONS SETUP
{ 7, "< BACK ", 2 },
{ 8, "REVERSE ", 2 },
{ 9, "ENDPOINTS ", 2 },
};
with this one
Menu GetSub(int parentId)
{
int position = 0;
Menu Filtered[menuLength];
for (int i = 0; i < menuLength; i++)
{
if (parentId == MainMenu[i].parentId)
{
Filtered[position] = MainMenu[i];
position++;
}
}
return Filtered;
}
I get the following errors
'Menu' does not name a type
could not convert '(Menu*)(& Filtered)' from 'Menu*' to 'Menu
So, how am i supposed to return the filtered array?
First of all, please use C++ containers when you are using C++. Don't use variable sized arrays (VLA) and there are lots of articles why using it is bad. Use std::vector and std::string instead.
const byte menuLength = 10;
struct Menu {
int id;
std::string Description;
int parentId;
};
std::vector<Menu> MainMenu = {
{ 1, "SYSTEM SETUP ", -1 },
{ 2, "FUNCTIONS SETUP", -1 },
{ 3, "FIRMWARE VER. ", -1 },
//SYSTEM SETUP
{ 4, "< BACK ", 1 },
{ 5, "MODEL SELECT ", 1 },
{ 6, "RX SETUP ", 1 },
//FUNCTIONS SETUP
{ 7, "< BACK ", 2 },
{ 8, "REVERSE ", 2 },
{ 9, "ENDPOINTS ", 2 },
};
std::copy_if
You can use std::copy_if to filter out the wanted menu.
std::vector<Menu> GetSub(const std::vector<Menu>& menu, int parentId)
{
std::vector<Menu> sub;
std::copy_if(menu.begin(), menu.end(), std::back_inserter(sub), [parentId](const Menu& m) {
return m.parentId == parentId;
});
return sub;
}
LIVE DEMO
ranges::view::filter
With Eric Niebler's range-v3 library, this becomes even more trivial.
std::vector<Menu> GetSubRange(const std::vector<Menu>& menu, int parentId)
{
return menu | ranges::view::filter([parentId](const Menu& m) { return m.parentId == parentId; })
}
You're trying to return an array of Menu objects via simply Menu object, you need to change function's prototype:
Menu GetSub(int parentId);
into
Menu * GetSub(itn parentId);
This function will return you a pointer to the array of Menu's, but then another problem will arise: you don't really know how many objects stored in an array. It can be solved by adding simple structure into your code:
struct MenuArray {
Menu * ptr;
int size;
}
And then remake your function like this:
MenuArray GetSub(int parentId)
{
int position = 0;
Menu * Filtered = new Menu[menuLength];
for (int i = 0; i < menuLength; i++)
{
if (parentId == MainMenu[i].parentId)
{
Filtered[position] = MainMenu[i];
position++;
}
}
return MenuArray{Filtered, position};
}
We can also simply use STL vector, and that is the simplest solution if you can use it.
using std::vector;
vector<Menu> GetSub(int parentId)
{
vector<Menu> Filtered(menuLength);
for (int i = 0; i < menuLength; i++)
if (parentId == MainMenu[i].parentId)
{
Filtered.push_back(MainMenu[i]);
}
return Filtered;
}
I am working on some arduino code and my program keeps on giving me this error,
ISO C++ forbids comparison between pointer and integer [-fpermissive]
I've tried searching on the internet to solve this issue but, either the solution is incorrect, or irrelevant. here is where the arduino software is saying the problem is,
if((millis - incLastDebounce) > debounceDelay) {
and if you need the rest of the code here it is,
#include <LiquidCrystal.h>
int freq = 0;
int change = 0;
const int incPin = 3;
const int setPin = 2;
int incButtonState;
int setButtonState;
int incPreviousState;
int setPreviousState;
int incLastDebounce;
int setLastDebounce;
const int debounceDelay = 50;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// put your setup code here, to run once:
lcd.begin(16, 2);
pinMode(setPin, INPUT);
pinMode(incPin, INPUT);
lcd.print("Frequency: " + freq);
}
void loop() {
// put your main code here, to run repeatedly:
int incReading = digitalRead(incPin);
int setReading = digitalRead(setPin);
if(setReading != setPreviousState) {
setLastDebounce = millis();
}
if(incReading != incPreviousState) {
incLastDebounce = millis();
}
if((millis - setLastDebounce) > debounceDelay) {
if(setReading != setButtonState) {
setButtonState = setReading;
}
if(setButtonState == HIGH) {
//Okay so here you will do your set lcd voodoo
}
}
if((millis - incLastDebounce) > debounceDelay) {
if(incReading != buttonState) {
incButtonState = incReading;
}
if(buttonState == HIGH) {
// here you can put the lcd code
change = change + 500;
if(change == 10500){
change = 0;
}
}
}
incPreviousState = incReading;
setPreviousState = setReading;
}
hopefully you can find the problem and help.
Looks like you're missing parentheses after millis, so instead of calling the function, you're trying to do arithmetic with its memory address.
This will probably work better:
if ((millis() - incLastDebounce) > debounceDelay) {
I wanted to expand on the Arduino Button and ForLoop tutorials by going through sequential inputs to check their status and illuminate the LED if any of them are pressed. Ultimately, I just want to do a single shot scan of the inputs before everything starts and anything that is closed (or shorted out) will be taken out of the rotation in the main program.
If the pins were sequential, I'd just do buttonIn++ starting at the first pin. Unfortunately, the input pins are not sequential but the names are.
I want to just add the int "1" to the end of char buttonIn = "myButton" and ++ the number in the string. That doesn't seem to be as easy as I had thought.
Now, I can do this with PHP easily
<?php
$myButton1="7";
$myButton2="15";
$myButton3="3";
$myButton4="11";
$myButton5="8";
for ($i=0;$i<=5;$i++) {
$buttonIn="myButton".$i;
echo $buttonIn." = ".$$buttonIn."\n";
}
?>
Which then outputs:
myButton1 = 7
myButton2 = 15
myButton3 = 3
myButton4 = 11
myButton5 = 8
Perfect, I can get both the variable name and its value.
However, this doesn't work with C. The commented out lines are what I've tried so far. Hopefully someone else has a better idea to do this without having to specify every single pin in the pre-run loop thus saving space and time.
const int myButton1 = 7;
const int myButton2 = 15;
const int myButton3 = 3;
const int ledPin = 13;
int buttonState = 0;
void setup() {
pinMode(myButton1, INPUT);
pinMode(myButton2, INPUT);
pinMode(myButton3, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
char buttonIn[13];
for (int x=1;x<=5;x++) {
// char buttonIn = "OSD1button",x;
// char buttonIn[13]="OSD1button",x;
// int sprintf(str, "OSD1button%d",x);
// sprintf(buttonIn,"OSD1button%d",x);
// strncat(buttonIn,x,2);
// char nameIn[12]="OSD1button";
//buttonIn=nameIn + x;
// sprintf(buttonIn, "%d", x);
char OSD="OSD1button";
// buttonIn=OSD+itoa(x,OSD,13);
strncpy(buttonIn,OSD,x);
buttonState = digitalRead(buttonIn);
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin,LOW);
}
}
}
Here's the current error message:
Arduino: 1.5.6-r2 (Windows 7), Board: "Arduino Due (Programming Port)"
OSD_Test.ino: In function 'void loop()':
OSD_Test:67: error: invalid conversion from 'const char*' to 'char'
OSD_Test:69: error: invalid conversion from 'char' to 'const char*'
OSD_Test:69: error: initializing argument 2 of 'char* strncpy(char*, const char*, size_t)'
OSD_Test:70: error: invalid conversion from 'char*' to 'uint32_t'
OSD_Test:70: error: initializing argument 1 of 'int digitalRead(uint32_t)'
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Thanks in advance!
Since Arduino actually provides a StringAdditonOperator http://arduino.cc/en/Tutorial/StringAdditionOperator you could use:
for(int x = 1; x <=5; x++) {
String desiredString = "Button"+x;
Serial.println(desiredString);
}
Which will output:
Button1
Button2
...
As far as I understand from the comments you want to do something like this:
int buttonArray[3] = {7,15,3}; //Or on whatever pins your buttons are
// Setup code and anything else you need goes here
void loop() {
for(int x = 0; x <= 3; x++) {
int buttonState = digitalRead(buttonArray[x]);
digitalWrite(ledPin,buttonState);
}
}
But be aware that this will change the state of the LED-Pin only to the last button state read.
Got it. This works great. Thanks.
const int myButton1 = 7;
const int myButton2 = 15;
const int myButton3 = 3;
const int myButton4 = 27;
const int myButton5 = 22;
const int myButton6 = 18;
const int myButton7 = 23;
const int myButton8 = 11;
const int myOutput1 = 8;
const int myOutput2 = 16;
const int myOutput3 = 4;
const int myOutput4 = 28;
const int myOutput5 = 24;
const int myOutput6 = 19;
const int myOutput7 = 25;
const int myOutput8 = 12;
Becomes
int myButton[8]={7,15,3,27,22,18,23,11};
int myOutput[8]={8,16,4,28,24,19,25,12};
Then add this to the setup
for (int i=0;i<8;i++) {
pinMode(myButton[i], INPUT);
pinMode(myOutput[i], OUTPUT);
}
I'm new to C++ from a java/python/etc background, and am trying to teach myself OO programming before I have to take a class on it next semester.
I'm trying to make an animation system using SFML, but am having some trouble with one of my class variables; it keeps resetting to 0 after I increment it. I'll start with the code and follow with a log output I'm using to help figure out what's going on.
SOLUTION: Being new to C++, I was an idiot and returned a new instance of my class in my getter functions; using [class]& func()... instead of [class] func() solved this, but now I have some refactoring to do.
Code (header):
...
typedef std::vector<Frame> frameVect; // (Frame defined above)
typedef std::vector<double> dubVect;
...
class limbAnim
{
private:
int limbNum;
int numFrames;
int curFrame;
frameVect frames;
public:
limbAnim(int limb, int nFrames, frameVect F);
<getters/setters>
void incCurFrame();
dubVect incrementAnimation(dubVect curPos, double curRot);
}
Code (cpp):
... (include vector, ofstream, etc)
std::ofstream AnimLog("log.log")
typedef std::vector<Frame> frameVect; // (Frame defined above)
typedef std::vector<double> dubVect;
...
limbAnim::limbAnim(int limb, int nFrames, frameVect F)
{
limbNum = limb;
curFrame = 0;
numFrames = nFrames;
frames = F;
}
void limbAnim::incCurFrame()
{
curFrame=curFrame+1;
if (curFrame >= numFrames)
{
curFrame = 0;
AnimLog << "Greater than." << std::endl;
}
}
dubVect limbAnim::incrementAnimation(dubVect curPos, double curRot)
{
AnimLog << limbNum << ", " << numFrames << std::endl;
if (numFrames > 0)
{
AnimLog << curFrame << std::endl;
dubVect curStepP = frames[curFrame].getStepPos();
double curStepR = frames[curFrame].getStepRot();
curPos[0] = curPos[0] + curStepP[0];
curPos[1] = curPos[1] + curStepP[1];
curRot = curRot + curStepR;
incCurFrame();
AnimLog << "Incremented: " << curFrame << std::endl;
}
dubVect retV = curPos;
retV.push_back(curRot);
return retV;
}
So, my log output looks good since I'm testing with 2 frames on limbs 6 & 8, except those limbs' curFrame seems to reset to 0 after incrementing:
...
5, 0
6, 2
0
Incremented: 1
7, 0
8, 2
0
Incremented: 1
9, 0
...
5, 0
6, 2
0
Incremented: 1
7, 0
8, 2
0
Incremented: 1
9, 0
...(ad nauseam)
Edit: Code calling the increment function.
(main.cpp)
// (Outside main loop.)
Animation walk_anim(12, "assets/anim/walk.dat");
// (Inside main loop.)
for (int i=0; i<12; i++)
{
dubVect animDat = walk_anim.getLimbFrame(i).incrementAnimation(limbPos[i], curDegs[i]);
dubVect newPos = getDVect(animDat[0], animDat[1]);
double newRot = animDat[2];
curDegs[i] = newRot;
if (curDegs[i] >= 360)
curDegs[i] -=360;
limbPos[i] = newPos;
}
getLimbFrame
Animation::Animation(int lNum, string fName)
{
numLimbs = lNum;
fileName = fName;
// Fill up limbVect with correct # of empty frames.
for (int i=0; i<numLimbs; i++)
{
frameVect emptyFVect;
limbAnim LA(i, 0, emptyFVect);
limbFrames.push_back(LA);
}
// Boring .dat parsing, populates the 'frames' var of each limbAnim.
loadAnim();
}
limbAnim Animation::getLimbFrame(int index)
{
if (index < numLimbs)
{
return limbFrames[index];
}
}
Hopefully you're aware that your functions take arguments by value, so they work on a copy of something.
You carefully avoided to show the really interesting code parts where you call incrementAnimation, most likely it follows the same bad pattern as the other functions.
I suggest reading up on how to pass objects by reference and const reference -- and how function arguments work in C++.
I think you need to declare that member variable, with the static keyword, then you can say it is a class variable, where it will be the shared for every instance of your class. Like this:
static int curFrame;
Then you need to initialize it from outside de class. Have in mind that declaration, is a lot different to initialization.
You can read about it here and here