#include "IRSensor.h"
#include "Turret.h"
#include "StepperButtonController.h"
#include "LoadBottleButton.h"
LoadBottleButton go(A3,1000);
void setup()
{
Serial.begin(9600);
Serial.println("Port Open");
}
void loop()
{
if(go.Read())
{
go.Monitor();
}
}
Above is the Main code
#ifndef LoadBottleButton_cpp
#define LoadBottleButton_cpp
#include "Arduino.h"
#include "ScaleObject.h"
#include "LoadBottleButton.h"
#include "Turret.h"
#include "StepperButtonController.h"
ScaleObject* so;
Turret* tPointer;
LoadBottleButton::LoadBottleButton(int pin, int debounce):StepperButtonController(pin,debounce)
{
}
void LoadBottleButton::Monitor()
{
Serial.println("In Monitor");
while(tPointer->getTurret().BottleCenterState==false)
{
Serial.println("In Monitor While Loop");
tPointer->Start();
SETUP = true;
load = true;
unload = !so->getScale().Empty();
Serial.println(load);
Serial.println(unload);
Serial.println(!so->getScale().Empty());
if(unload)
{
unload=!so->getScale().Empty();
}
else if(load && !so->getScale().Empty())
{
load = !tPointer->BottleCentered();
}
if(!load && !unload && SETUP)
{
tPointer->Stop();
SETUP = false;
}
}
}
#endif
And above is the LoadBottleButtonClass.cpp file.
#ifndef Turret_cpp
#define Turret_cpp
//#include "HX711.h"
#include "Turret.h"
#include "Arduino.h"
#include "StepperButtonController.h"
#include "ScaleObject.h"
#include "IRSensor.h"
//StepperButtonController Clear(9,1000);
void StepTurret();
Turret turret(2,3,4,StepTurret);
void StepTurret()
{
turret.Step();
}
ScaleObject* tso;
IRSensor* irs;
Turret::Turret()
{
}
Turret Turret::getTurret()
{
return turret;
}
Turret::Turret(int en, int dir, int clk, void(*stepFunction)()):stepper2(en,dir,clk,stepFunction)
{
tso->getScale().tare();
tso->getScale().set_gain(128);
tso->getScale().set_scale(-3483.4);
}
void Turret::SeekBottleCenter()
{
Start();
while(irs->IRState()==1)
{
Serial.println("High");
Serial.println(irs->IRState());
}
while(irs->IRState()==0)
{
Serial.println("Low");
}
}
bool Turret::BottleCentered()
{
return turret.BottleCenterState;
}
void Turret::ClearFunction()
{
wt = tso->getScale().get_units();
while(wt>5)
{
Serial.println("Clearing");
wt = tso->getScale().get_units();
Rotate(20);
}
}
#endif
And above is the Turret.cpp file.
#ifndef IRSensor_cpp
#define IRSensor_cpp
#include "Arduino.h"
#include "IRSensor.h"
IRSensor i(5);
IRSensor::IRSensor(int pin)
{
IRSensorPin = pin;
pinMode(pin,INPUT);
}
int IRSensor::IRState()
{
return digitalRead(i.IRSensorPin);
}
#endif
And above is the IRSensor.cpp file. So essentially I press the go button declared in my main, that button calls monitor in the LoadBottleButton.cpp file, that method uses a turret point to get access to the Turret.cpp methods and a boolean named BottleCenterState. But the code only gets so far, it stops after printing "In" of the Serial.println("In Monitor") line. Why is that?
Don't count on the output to tell you where the error is. That serial print may have completed successfully and the message is buffered in an output stream waiting for a chance to be written to the serial port.
A much more likely cause of the crash is the line below the serial print.
Serial.println("In Monitor");
while(tPointer->getTurret().BottleCenterState==false)
tPointer is used and I don't see anywhere in the provided code it is assigned a valid, dereferencable pointer. Dereferencing an undefined pointer results in undefined behaviour, and in this case probably a crash. Even if it isn't the crash you are seeing, this is almost certainly wrong.
How to fix it?
From the code provided it doesn't look like tpointer needs to be a pointer at all.
Turret turret;
May be all you need. Allocating turret statically eliminates the possibility of pointer and memory management bugs and reduces the chance of leaks.
Otherwise,
Turret* tPointer = new Turret();
But this leaves you with the problem of how and when do you delete tPointer;.
Check that your string doesn't contain a NULL character. This will terminate the string abruptly.
Related
I am a very new coder, and I'm trying to code a program that when SW1 is pressed on the Tivaware launch board, it lights the red LED and when I press both SW1 and SW2 the Blue LED is on. when I run the code shown below only the Red LED is on and there is no response from the board.
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
bool sw1_not_pressed,sw2_not_pressed,sw1_pressed,sw2_pressed;
int main(void){
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN);
while(1)
{
sw1_not_pressed = GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4 );
sw2_not_pressed = GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_0 );
sw1_pressed = !sw1_not_pressed;
sw2_pressed = !sw2_not_pressed;
if(sw1_pressed)
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
}
else
{
if(sw2_pressed && sw1_pressed)
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2,0x00 );
}
}
}
}
I am very grateful for any help given and thank you for responding to my question.
I am working on a lua script interrupt project, I want to use std::Stack and lua coroutine to save the context. But when I set stacksize to more than 38, it randomly crashes in lua_resume and lua_close.
test.lua:
local stacksize = 40 --When changing stacksize less than 30, it runs fine.
function heavy_function(i)
print("heavy_function start",i)
if i < stacksize then
coroutine.yield(i+1)
end
print("heavy_function end",i)
end
main.cpp:
#ifdef __cplusplus
extern "C" {
#endif
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#ifdef __cplusplus
}
#endif
#include <iostream>
#include <unistd.h>
#include <ctime>
#include <stdio.h>
#include <string>
#include <stack>
using namespace std;
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
int ret = luaL_dofile(L, "test.lua");
if (ret != 0)
{
// Error loading script. Return.
printf("luaL_dofile error \n");
return -1;
}
// Add a count hook that will trigger after "count" number instructions
//lua_sethook(L, LUAHook, LUA_MASKLINE, 0);
stack<lua_State *> Lstack;
Lstack.push(lua_newthread(L));
int init = 1;
do{
lua_getglobal(Lstack.top(), "heavy_function");
lua_pushinteger(Lstack.top(),init);
ret = lua_resume(Lstack.top(),L,1);
if(ret == LUA_YIELD)
{
init = luaL_checkinteger(Lstack.top(),-1);
Lstack.push(lua_newthread(L));
}
else if(ret == 0)
{
//lua_close(Lstack.top());
lua_gc(L,LUA_GCCOLLECT,0);
cout<<"Memory Usage:"<<lua_gc(L,LUA_GCCOUNT,0)<<endl;
Lstack.pop();
}
else{
cout<<"error"<<endl;
return -1;
}
}while(Lstack.size()>0);
//printf("lua script interrupted \n");
lua_close(L);
return 0;
}
Compiler option:
g++ -g main.cpp -o test -llua -ldl
I suspect that I made a mistake while calling lua_newthread.So I made a stack check before calling lua_newstate and it became normal.
if(ret == LUA_YIELD)
{
init = luaL_checkinteger(Lstack.top(),-1);
Lstack.push(lua_newthread(L));
cout<<"lua_checkstack(L,10) = "<<lua_checkstack(L,1)<<endl;//Add a line in line 47
}
Wanted to know if I made a mistake in this and how can I make it right?
You are overflowing the Lua stack by continuously generating new Lua threads and leaving its Lua objects on stack.
lua_newstack() not only returns a pointer to lua_State structure, it also leaves a value of type LUA_TTHREAD on a stack in your L state. You should either accommodate the Lua stack accordingly, or manage returned Lua threads in some other way.
Quick and dirty "fix" would be to call lua_checkstack(L, 10); right before your Lstack.push(lua_newthread(L)); line. It allows your code to run as is, but the stack would continuously grow. Instead you should grab the new thread object off the stack and put it in some Lua table until the time comes for it to be deleted.
I am writing code for the Azure IoT Hub, which requires the use of c-functions in the Arduino loop(). The issue that I'm having is that if I pass a pointer to a float created in the c-file to a c++ file and modify the value, what is seen in the c-file after the c++ function returns is gibberish.
Here's a psuedocode example, and a working example is included below:
loop() in ino file:
runs runInLoop(), defined in the c-file RunTest.c
runInLoop() in RunTest.c:
create a float
pass the address to modifyFloat(float *address) defined in FloatTest.cpp
print the value of the float after modifyFloat() returns.
modifyFloat(float *address) in FloatTest.cpp:
assign a vale to *address
print the value
return
I've executed this pseudocode in the working example below and the result in the serial monitor is:
Value assigned in modifyFloat: 22.55
The value that was returned is: 1077316812
I'm using an Adafruit Huzzah Feather, configured exactly as they indicate in their documentation.
Here is a working example:
azure_troubleshoot.ino
#include "RunTest.h"
void setup()
{
initSerial();
}
void loop()
{
Serial.println("Starting main loop!\r\n");
runInLoop();
}
void initSerial()
{
Serial.begin(9600);
}
RunTest.c
#include "FloatTest.h"
void runInLoop(void)
{
while(1)
{
float testValue;
modifyFloat(&testValue);
(void)printf("The value that was returned is: %d\r\n", testValue);
delay(1000);
}
}
RunTest.h
#ifndef RUNTEST_H
#define RUNTEST_H
#ifdef __cplusplus
extern "C" {
#endif
void runInLoop(void);
#ifdef __cplusplus
}
#endif
#endif // RUNTEST_H
FloatTest.cpp
#include <Arduino.h>
#include "FloatTest.h"
void modifyFloat(float *address)
{
*address = 22.55;
Serial.print("Value assigned in modifyFloat: ");
Serial.println(*address);
}
FloatTest.h
#ifndef FLOATTEST_H
#define FLOATTEST_H
#ifdef __cplusplus
extern "C" {
#endif
void modifyFloat(float* address);
#ifdef __cplusplus
}
#endif
#endif // FLOATTEST_H
The issue was the use of the %d in the printf string in RunTest.c. Updating the code to that shown below fixes the issue and makes the output:
Value seen in modifyFloat: 22.55
The value that was returned is: 22.55
RunTest.c
#include "FloatTest.h"
void runInLoop(void)
{
while(1)
{
float testValue;
modifyFloat(&testValue);
char str_tmp[6];
dtostrf(testValue, 4, 2, str_tmp);
(void)printf("The value that was returned is: %s\r\n", str_tmp);
delay(1000);
}
}
I get a lot of undefined references. I don't know what I'm doing wrong.
I'm getting the following errors:
undefined reference to 'LetteroidField::start()'
undefined reference to 'LetteroidField::setTitle(std::string)'
undefined reference to 'Letteroid::setletter(char)'
undefined reference to 'Letteroid::setLetter()'
undefined reference to 'Letteroid::setCoords()'
undefined reference to 'Letteroid::erase()'
and other letteroid references.
I'm not done with the other classes, but I don't know why I'm getting these errors. Am I not using #include "" correctly?
This is my professor's sample code. I contacted him but he is not answering (its an online class).
#include "letteroidfield.h"
#include "letteroid.h"
#include "blinkingletteroid.h"
#include "jumpingletteroid.h"
#include "movingletteroid.h"
#include <stdlib.h> /* srand, rand */
#include <time.h>
/// include your derived classes here
int main()
{
LetteroidField screen;
screen.start();
screen.setTitle("Ken's example for the class, press 'x' to quit");
BlinkingLetteroid one;
BlinkingLetteroid two;
BlinkingLetteroid three;
one.setLetter('!'); /// character
one.setCoords(5, 10); /// row, col
two.setLetter('h');
two.setCoords(7, 9);
three.setLetter('#');
three.setCoords(15, 57);
JumpingLetteroid four;
four.setLetter('j');
four.setCoords(rand() % 21, rand() % 21);
MovingLetteroid five;
five.setLetter('m');
int x = 20;
int y = 20;
while (x >= 1)
{
--x;
}
while (y >= 1)
{
--y;
}
if (x == 1)
{
x = 20;
}
if (y == 1)
{
x = 20;
}
five.setCoords(x,y);
/// create and initialize your letteroids here
while ( screen.waitForKeyPress() ) /// keep going until 'x' is pressed
{
one.blink();
two.blink();
three.blink();
/// call the function that draws your letteroids here
}
screen.end();
return 0;
}
#ifndef _LETTEROIDFIELD_H_
#define _LETTEROIDFIELD_H_
#include <string>
class LetteroidField
{
public:
void start(); /// start up the screen for letteroids
bool waitForKeyPress(); /// wait for any key to be pressed (return
void end(); /// shut down the screen and return it to
void setTitle(std::string); /// diplay the title
};
#endif
#ifndef _LETTEROID_H_
#define _LETTEROID_H_
class Letteroid
{
public:
void setCoords(int, int);// set the position(down, across)
void setLetter(char); // set the character
int getX(); // get the position down
int getY(); // get the position across
void erase(); // erase the letteroid from the screen
void draw(); // draw the letteroid to the screen
private:
int myX;
int myY;
char myLetter;
};
#endif
The question you need to ask yourself is: Where are those classes defined?
If the answer is: "in a shared library (file extension ".so") provided alongside the header", then you'll need to link against it by adding at least the following to your compilation command:
g++ main.cpp -L</path/to/library> -l<library_name>
If the answer is: "in a static library (file extension ".a", AKA archive) provided alongside the header", then you'll need include it in your binary by adding at least the following to your compilation command:
g++ main.cpp <library_name.a>
If the answer is: "in a bunch of source files provided alongside the header", then you'll need to include them in your binary by adding at least the following to your compilation command:
g++ main.cpp <source_file1.cpp> <source_file2.cpp> ...
I looked around and I couldn't find the answer to how exactly to do this. I am trying to use Pantheios for logging and I want to write to an external file (otherwise whats the point). I am following one of the examples provided but It doesn't seem to be making the log file anywhere. Here is the code:
Edit: Also pantheios_be_file_setFilePath is returning -4 (PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE) so thats.....not helpful
#include "stdafx.h"
#include <pantheios/pantheios.hpp>
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>
#include <pantheios/implicit_link/be.file.h>
#include <pantheios/frontends/fe.simple.h>
#include <pantheios/backends/bec.file.h>
#include <pantheios/inserters/args.hpp>
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("LogTest");
int _tmain(int argc, _TCHAR* argv[])
{
try
{
pantheios_be_file_setFilePath(PANTHEIOS_LITERAL_STRING("testlogforme.log"), PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
pantheios::log(pantheios::debug, "Entering main(", pantheios::args(argc,argv, pantheios::args::arg0FileOnly), ")");
pantheios::log_DEBUG("debug yo");
pantheios::log_INFORMATIONAL("informational fyi");
pantheios::log_NOTICE("notice me!");
pantheios::log_WARNING("warning!!");
pantheios::log_ERROR("error omg");
pantheios::log_CRITICAL("critical!!!");
pantheios::log_ALERT("alert mang");
pantheios::log_EMERGENCY("EMERGENCY!!!!!");
pantheios_be_file_setFilePath(NULL, PANTHEIOS_BEID_ALL);
system("pause");
return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{
pantheios::log_ALERT("out of memory");
}
catch(std::exception& x)
{
pantheios::log_CRITICAL("Exception: ", x);
}
catch(...)
{
pantheios::puts(pantheios::emergency, "Unexpected unknown error");
}
return EXIT_FAILURE;
}
Maybe I'm not calling a method or maybe its not being saved to a good location?
It turns out that some of the examples out there for pantheios are incorrect. You DO need to call pantheios_init() even if you are in C++. Here Is the example I got to work after deleting all my code and implementing an example that works.
// Headers for main()
#include <pantheios/pantheios.hpp>
#include <pantheios/backends/bec.file.h>
// Headers for implicit linking
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.file.h>
PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "testLOL";
int main()
{
if(pantheios::pantheios_init() < 0)
{
return 1;
}
pantheios::log_NOTICE("log-1"); // save until log file set
pantheios_be_file_setFilePath("mylogfile.log"); // sets log file; write "log-1" stmt
pantheios::log_NOTICE("log-2"); // write "log-2" stmt
pantheios_be_file_setFilePath(NULL); // close "mylogfile"
pantheios::log_NOTICE("log-3"); // save until log file set
pantheios_be_file_setFilePath("mylogfile2.log"); // sets log file; write "log-3" stmt
pantheios::log_NOTICE("log-4"); // write "log-4" stmt
//system("pause");
return 0;
} // closes "mylogfile2" during program closedown
I found the example on a different post on stack overflow but like I said, the built in examples do not work.