I would like to use the timer_us function of the NewPing library in order to run a function every second without blocking. My minimal example looks like this:
// setup timer
#include <NewPing.h>
timer_us(1000, sensoring);
void setup() {
Serial.begin(19200)
}
void loop() {}
void sensoring() {
Serial.print("ok, it's working")
}
But it is not compiling because of:
expected constructor, destructor, or type conversion before '(' token
My hardware is:
Arduino: 1.8.3 (Mac OS X), Board: "Arduino Nano, ATmega328"
Two mistakes:
The syntax is NewPing::timer_ms(.
Put that line inside setup().
Related
I'm making a program where a buzzer activates if the accelerometer is tilted a certain number of degrees. I'm getting an error that says "'I2C_MODE' was not declared in this scope." I'm using a Grove Beginner Kit, so all of the parts are automatically connected to each other. I downloaded Seeed_Arduino_LIS3DHTR library from the following link: https://github.com/Seeed-Studio/Seeed_Arduino_LIS3DHTR and used sample code from the Grove Beginner Kit for Arduino Guide that came with the board, so everything should work properly. I'm getting this error and don't want to move further with the project until I figure out what's causing this error.
#include <LIS3DHTR.h>
//Gravity Acceleration
#include "LIS3DHTR.h"
#ifdef SOFTWAREWIRE
#include <SoftwareWire.h>
SoftwareWire myWire(3, 2);
LIS3DHTR<SoftwareWire> LIS(I2C_MODE); //IIC This is what the error
#define WIRE myWire
#else
#include <Wire.h>
LIS3DHTR<TwoWire> LIS(I2C_MODE);//IIC THIS IS WHERE THE ERROR OCCURS
#define WIRE Wire
#endif
void setup() {
Serial.begin(9600);
while (!Serial) {};
LIS.begin(WIRE); //IIC init
delay(100);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
}
void loop() {
if (!LIS) {
Serial.println("LIS3DHTR didn't connect.");
while (1);
return;
}
//3 axis
Serial.print("x:"); Serial.print(LIS.getAccelerationX()); Serial.prin
t(" ");
Serial.print("y:"); Serial.print(LIS.getAccelerationY()); Serial.prin
t(" ");
Serial.print("z:"); Serial.println(LIS.getAccelerationZ());
delay(500);
}
The docs you linked have a different instantiation than what you have!
Try passing Wire to the .begin method rather than to LIS (which presumably does exist in Wire.h and likely also exists in SoftwareWire.h)
Plausibly putting LIS.begin() in setup() is needed, though it doesn't seem to matter from their examples
LIS3DHTR<TwoWire> LIS; //IIC
LIS.begin(Wire, 0x19)
This is a strange one for me and I certainly did not expect to get so completely stumped in my first day or so of learning the STM32CubeIDE. The first order of the day was making the onboard led blink with
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
HAL_Delay(500);
Going through the New Project/pin config and code generator this worked fine inside the while loop provided in the main.c file but when I called my own function inside the loop with the HAL commands it stops working. The code loops and calls my function mainLoop() but any HAL commands inside my function don't do anything.
Why is this - am I missing some kind of handle that must be passed or an #include to extend the scope of HAL commands within a source file and not just main() itself?
while (1)
{
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
void mainLoop(void);
// HAL_Delay(500); // works fine when uncommented
}
} // end of main()
void mainLoop(void)
{
HAL_Delay(200); // this does nothing
} // no HAL commands actioned
Yes, you are quite right and thanks for that. My stupid question was the result of me actually trying to put mainLoop() in another .cpp file, with appropriate .h header file containing the prototype and call it from the main.c while loop. Since I got an undefined reference to mainLoop linker error, I moved mainloop() back into main.c and then tried to run the prototype. Doh!
So, despite my flawed attempt to simplify the problem, I still cannot call my mainloop() function with its HAL commands residing in another .cpp file. Additionally, although I have yet to reach this point, are the HAL commands available in every project source file or will I need to #include a particular header?
You should call function in the following way.
while (1)
{
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
mainLoop();
// HAL_Delay(500); // works fine when uncommented
}
} // end of main()
void mainLoop(void)
{
HAL_Delay(200); // this does nothing
}
This is not the way to call the function.
void mainLoop(void); //function declaration (prototype) needed as mainLoop is defined after the call
int main(void)
{
while (1)
{
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
mainLoop(); //call to the function
}
}
void mainLoop(void) // function definition
{
HAL_Delay(200); // this does nothing
}
As your mainLoop call is before the function definition, you need to provide the function prototype to tell compiler that parameters takes the function and what it returns.
Then you need to call the function by mainLoop() - not void mainLoop()
I have a question regarding scheduler implementation. I have tried to implement a scheduler according to my understanding.
In this example, i have taken advantage of the Systick handler provided by STM32, so my handler looks somewhat like this:
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
if(ticks_for_scheduler++==100)
ticks_for_scheduler=0;
}
I have a scheduler.h file which looks like this:
void (*task1)() = read_temp;
void (*task2)() = Display_temp_lcd;
and my scheduler.c looks like this:
extern uint16_t ticks_for_scheduler;
void sched_system()
{
if(ticks_for_scheduler==20)
(*task1)();
if(ticks_for_scheduler==40)
{
(*task2)();
}
}
The function sched_system is called in main(){while(1){sched_system();}My goal is to execute task1 every 20ms, and task2 every 40ms, but somehow I'm not able to get it right. I'm not sure what I'm doing wrong? I don't see the results on my LCD as expected.
Disclaimer: asked over at perlmonks.
I hope I'm describing and depicting my issue properly... In XS, I'm trying to send a callback into an external library's function, where the callback has Perl specific functions. The XSUB is passed as a function pointer to an external C function. The XSUB callback being sent in turn calls back to a sub in the `main` perl application:
void callback(){
dSP;
PUSHMARK(SP);
call_pv("p_callback", G_DISCARD|G_NOARGS);
}
// example extern call
externFunc(&callback);
This segfaults. I think it's because the external library doesn't understand the perl functions that are being called. Things work fine if I call the C `callback()` function directly though.
Is there some magic that I can do to make the external library "see" the Perl C functions, or am I doing something wrong?
Here's the code I'm testing with:
use warnings;
use strict;
use Inline ('C' => 'DATA', libs => '-lwiringPi');
init();
setInterrupt(27, 3);
# direct call
callback();
# on() triggers the external function and sends
# it the callback
on(27);
sub p_callback {
print "in perl callback\n";
}
__DATA__
__C__
#include <stdlib.h>
#include <stdio.h>
#include <wiringPi.h>
void init();
void on(int pin);
void off(int pin);
void setInterrupt(int pin, int edge);
void callback();
void init(){
printf("in init\n");
wiringPiSetup();
}
void on(int pin){
pinMode(pin, 1);
digitalWrite(pin, 1);
}
void off(int pin){
digitalWrite(pin, 0);
pinMode(pin, 0);
}
void setInterrupt(int pin, int edge){
wiringPiISR(pin, edge, &callback);
}
void callback(){
dSP;
PUSHMARK(SP);
call_pv("p_callback", G_DISCARD|G_NOARGS);
}
Output:
in init
in perl callback
Segmentation fault
If I remove the perl specific C calls from within the callback and just do a `printf()` or other pure-C work, things proceed without a segfault.
Just came across this question and thought I'd give it my own answer as I did resolve it some time ago.
There were some important bits I was missing to set the Perl context, as well as within the C exec_perl_callback() function.
use warnings;
use strict;
use Inline 'C';
use Inline 'NoClean';
sub p_callback {
print "hello, world from perl!\n";
}
exec_perl_callback('p_callback');
__END__
__C__
#define PERL_NO_GET_CONTEXT
PerlInterpreter * mine;
void callback(char* perl_callback){
PERL_SET_CONTEXT(mine);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUTBACK;
exec_perl_callback(perl_callback, G_DISCARD|G_NOARGS);
FREETMPS;
LEAVE;
}
Output:
hello world, from perl!
I have an Arduino project where I read data from a webserver.
I have an EthernetClient that reads the data character by character in a callback function.
My working code looks like (only the relevant parts):
void setup() {
Serial.begin(9600);
...
}
void loop() {
char* processedData = processData(callback); // this is in a external lib
}
boolean callback(char* buffer, int& i) {
...
if (Client.available()) {
char c = client.read();
buffer[i++] = c;
Serial.print(c);
}
...
}
This works without any problems (reading and processing the data), but when I remove Serial.begin(9600); and Serial.print(c); it stops working and I don't know why? The only thing changed is that the char c is not printed. What could be the problem?
A common reason why callback functions change their behavior when seemingly unrelated code is altered, is optimizer-related bugs.
Many embedded compilers fail to understand that a callback function (or an interrupt service routine) will ever be called in the program. They see no explicit call to that function and then assumes it is never called.
When the compiler has made such an assumption, it will optimize variables that are changed by the callback function, because it fails to see that the variable is changed by the program, between the point of initialization and the point of access.
// Bad practice example:
int x;
void main (void)
{
x=5;
...
if(x == 0) /* this whole if statement will get optimized away,
the compiler assumes that x has never been changed. */
{
do_stuff();
}
}
void callback (void)
{
x = 0;
}
When this bug strikes, it is nearly impossible to find, it can cause any kind of weird symptoms.
The solution is to always declare all file scope ("global") variables shared between main() and an interrupt/callback/thread as volatile. This makes it impossible for the compiler to make incorrect optimizer assumptions.
(Please note that the volatile keyword cannot be used to achieve synchronization nor does it guarantee any memory barriers. This answer is not in the slightest related to such issues!)
A guess: Because without the serial driver started, there is no data to process, and therefore your callback is not hit.
What were you hoping the serial callback to be doing in the absence of data?
Providing more information about Client and processData may help.