Good point psb777. I will see what Spark dies in their isr(s).
Hi,
I just pulled a copy of the SparkIntervalTimer library from GitHub (https://github.com/pkourany/SparkIntervalTimer), and I’m running into some compile time issues. I’m building on my local machine which seems to be set up properly. After adding the SparkIntervalTimer.cpp to the build.mk file, the compilation generates a number of warnings, both for the module itself and for the files that include the .h file.
Building file: ../src/SparkIntervalTimer.cpp
Invoking: ARM GCC CPP Compiler
mkdir -p obj/src/
arm-none-eabi-gcc -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -I../inc -I../../core-common-lib/CMSIS/Include -I../../core-common-lib/CMSIS/Device/ST/STM32F10x/Include -I../../core-common-lib/STM32F10x_StdPeriph_Driver/inc -I../../core-common-lib/STM32_USB-FS-Device_Driver/inc -I../../core-common-lib/CC3000_Host_Driver -I../../core-common-lib/SPARK_Firmware_Driver/inc -I../../core-communication-lib/lib/tropicssl/include -I../../core-communication-lib/src -I. -ffunction-sections -Wall -fmessage-length=0 -MD -MP -MF obj/src/SparkIntervalTimer.o.d -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD -DDFU_BUILD_ENABLE -DRELEASE_BUILD -fno-exceptions -fno-rtti -c -o obj/src/SparkIntervalTimer.o ../src/SparkIntervalTimer.cpp
In file included from ../src/SparkIntervalTimer.cpp:22:0:
../inc/SparkIntervalTimer.h:53:74: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
const uint16_t SIT_PRESCALERu = (uint16_t)(SystemCoreClock / 1000000) - 1; //To get TIM counter clock = 1MHz
^
../inc/SparkIntervalTimer.h:54:71: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
const uint16_t SIT_PRESCALERm = (uint16_t)(SystemCoreClock / 2000) - 1; //To get TIM counter clock = 2KHz
^
../src/SparkIntervalTimer.cpp: In member function 'void IntervalTimer::start_SIT(uint16_t, bool)':
../src/SparkIntervalTimer.cpp:172:10: warning: statement has no effect [-Wunused-value]
scale == uSec; // Default to microseconds
^
../src/SparkIntervalTimer.cpp: In member function 'void IntervalTimer::interrupt_SIT(action)':
../src/SparkIntervalTimer.cpp:244:15: warning: variable 'TIMx' set but not used [-Wunused-but-set-variable]
TIM_TypeDef* TIMx;
^
../src/SparkIntervalTimer.cpp: In member function 'void IntervalTimer::start_SIT(uint16_t, bool)':
../src/SparkIntervalTimer.cpp:185:43: warning: 'TIMx' may be used uninitialized in this function [-Wmaybe-uninitialized]
TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);
^
../src/SparkIntervalTimer.cpp: In member function 'void IntervalTimer::stop_SIT()':
../src/SparkIntervalTimer.cpp:231:18: warning: 'TIMx' may be used uninitialized in this function [-Wmaybe-uninitialized]
TIM_DeInit(TIMx);
^
Of those warnings, the one about the use of the ‘==’ instead of the ‘=’ is a bigger issue. But, the other warnings are causing some concern as well. (I would like to have completely clean compiles)
I can fix the equality vs comparison error, but not sure about the impact of the other warnings. Is it safe to enable the specified compiler options to build cleanly?
One final question. In the earlier entries in the thread, there was a concern that the use of specific timers would affect the operation of various pins when analogWrite was being used. Is this still a concern, or has the library found a way to allow the timers to operate in a manner that will not mess up the analog output pins.
Thanks,
johnbo
@johnbo, we fixed those compile issues not too long ago! Do you have the lastest version?
Hi,
I pulled the source files from GitHub about an hour ago. Have the tool libraries or other elements changed? Those are a couple of weeks code (the source and tools).
I’m still a novice with Git, for these files I took the easy way out and pulled down the ZIP file and manually moved the .cpp and .h files.
Should I be doing something different?
Thanks,
johnbo
@johnbo, I just did a local compile with the latest master and it compiled just fine. I assume that you put the demo code in application.cpp?
@peekay123, I didn’t use the demo code (looked at it a bunch), but wrote my own ISR Handler. This is working fine and behaving pretty much as expected.
I suspect that my problem might be how I’m getting the code. I went to the GitHub page and clicked on the download ZIP icon. I then extracted the SparkIntervalTime.(cpp|.h) files in the core-firmware directory. As I stated, I’m still learning git, so maybe I’m loading the wrong versions of the files.
I don’t see a version tag in the file nor how to pull one from git. Sounds like I to learn how to use git better.
@johnbo, I was just re-reading the your post. Those warning can be ignored dude! I have yet to see a completely “clean” compile without some warning
Thanks, I’ll ignore them for a bit longer.
The timer library seems to working well. Thanks for putting that together.
Later,
johnbo
Hi @peekay123, now that I’ve got my code running using the IntervalTimer library, I’d like to offer a suggestion or 2.
-
The interaction between the existing uses of the timers and the
IntervalTimer library really needs to be documented. I had a
analogWrite operation using A0 and had setup a 100 ms timer. With my
scope, the rate that my handler was actually being called was about 2 ms. The
PWM function of A0 seemed to be working fine. In my code the PWM was
setup prior to the interval timer being established. I saw in one of
your posts, a list of some pins that were associated with certain
timers, but this really doesn’t provide enough detail and probably should be part of the actual documentation. -
If there are interactions that can be predicted by the user, it would be good to
have a way to create the timer object and force it to use a timer
that would be unused. Of course this would require that the
interactions or pre-existing constraints of the timers be known (see
above).
I like the library and other than wrestling with the rate issue, it came up with very little effort (unlike some of the messes I waded through on some LCD I2C backpack code).
Thanks,
johnbo
@johnbo, excellent suggestions! I will look at allowing the user to select a specific timer resource. As for the documentation, it’s one of those things I put on my todo list and, well, uhmm…
I have followed @johnbo’s excellent recommendations and updated the SparkIntervalTimer library. Besides updating the documentation to show the hardware timer impact on PWM pins, I have added:
- The ability to manually allocate one of the three hardware timers (TIMER2, TIMER3, TIMER4)
- The ability to enable/disable an allocated timer’s interrupt without having to release/recreate the timer
- The ability to reset an allocated timer’s time and timebase without having to release/recreate the timer
- The ability to get an allocated timer’s allocated hardware timer id
Hi I have problem to use this library to check wifi status and reconnect if needed. The problem is with Network.connect() function - when executing it then timerlibrary dies and nothing prints out to Serial. building my code with: make DEBUG_BUILD=y
Here is my code:
/* Timers */
IntervalTimer dataSyncTimer;
IntervalTimer wifiTimer;
void setup()
{
Serial.begin(115200);
while(!Serial.available());
dataSyncTimer.begin(dataSyncFunc, 10000, hmSec);
wifiTimer.begin(wifiCheckFunc, 3000, hmSec);
}
void loop(void)
{
}
/* Datasync function */
void dataSyncFunc()
{
LOG("Start data Sync");
LOG("End data Sync");
}
/* Check WIFI connection */
void wifiCheckFunc()
{
LOG("Start WIFI check");
// Check if WIFI is connected
if(Network.ready())
{
LOG("WIFI: connected");
// Connect to Spark server
Spark.connect();
}
else
{
// Connect to network
if(!Network.connecting())
{
LOG("WIFI: disconnected, try to connect...");
Network.connect();
}
else
{
LOG("WIFI: connected YYYYYYY.");
}
}
LOG("End WIFI check");
}
/* Spark debug interface */
void debug_output_(const char *p)
{
Serial.print(p);
}
Can you @peekay123 check this? Thanks!
@markopraakli, interrupt service routines (ISR) cannot be long nor blocking. The function Network.connect() is a blocking function which basically disrupts the ISR and the hangs things.
In your case, you have a couple of choices. First, have the dataSyncFunc() and wifiCheckFunc() functions in your main loop triggered by a flag that is set in each respective ISR.
Second, don’t use SparkIntervalTimer and use the elapsedMillis library to make simple timers in your loop(). When each timer elapses, you run the code you want and reset the timer.
Hi @peekay123, I am needing some clarification on the usage of this library. When this library is being used, does it take over all interrupt functions for the core or can I also use attachInterrupt() as well?
Thanks!
@techbutler, the SparkIntervalTimer library only uses the TIMER interrupts so you are free to use attachInterrupt() as you require.
Thanks peekay123, I thought that was the case, but I was getting a compile error that was making me think differently. What I'm working on is very similar to a thread you participated in back in march
At that point, the IntervalTimer library did not exist. I am not using the power switch tail, but the AC Dimmer Circuit by Robert Twomey.
I've been successful using his example code on the arduino. Granted, his code uses TimerOne. So, I've been trying my hand at modifying that code with the IntervalTimer,but am getting the following error:
"ac_dimmer_3.cpp:19:51: fatal error: SparkIntervalTimer/SparkIntervalTimer.h: No such file or directory
void zero_cross_detect();"
I''m guessing this isn't going to be as plug and play as I was hoping
My modified code below. Thanks again
/*
AC Light Control
Updated by Robert Twomey <rtwomey@u.washington.edu>
Changed zero-crossing detection to look for RISING edge rather
than falling. (originally it was only chopping the negative half
of the AC wave form).
Also changed the dim_check() to turn on the Triac, leaving it on
until the zero_cross_detect() turn's it off.
Adapted from sketch by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30
*/
//#include <TimerOne.h> // Avaiable from http://www.arduino.cc/playground/Code/Timer1
#include "SparkIntervalTimer/SparkIntervalTimer.h"
IntervalTimer myTimer;
void dim_check(void);
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
const uint8_t AC_pin = D5; // Output to Opto Triac
int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff
int inc=1; // counting up or down, 1=up, -1=down
//int freqStep = 65; // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want.
//
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.
// To calculate freqStep you divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps.
//
// (1000000 uS / 120 Hz) / 128 brightness steps = 65 uS / brightness step
//
// 1000000 us / 120 Hz = 8333 uS, length of one half-wave.
void setup() { // Begin setup
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(D1, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
myTimer.begin(dim_check, 65, uSec);
//Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
//Timer1.attachInterrupt(dim_check, freqStep);
// Use the TimerOne Library to attach an interrupt
// to the function we use to check to see if it is
// the right time to fire the triac. This function
// will now run every freqStep in microseconds.
}
void zero_cross_detect() {
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i=0;
digitalWrite(AC_pin, LOW); // turn off TRIAC (and AC)
}
// Turn on the TRIAC at the appropriate time
void dim_check() {
if(zero_cross == true) {
if(i>=dim) {
digitalWrite(AC_pin, HIGH); // turn on light
i=0; // reset time step counter
zero_cross = false; //reset zero cross detection
}
else {
i++; // increment time step counter
}
}
}
void loop() {
dim+=inc;
if((dim>=128) || (dim<=0))
inc*=-1;
delay(18);
}
@techbutler, are you compiling on the web IDE, with Spark CLI or locally? If on the IDE, did you include the SparkIntervalTimer library with your app?
web IDE, @peekay123, and I did include the library.
@techbutler, crap!! I re-read the error and I believe it has nothing to do with the SparkIntervalTimer library. You use zero_cross_detect() in setup() BEFORE you declare that function. So either add the function prototype:
void zero_cross_detect();
before setup() or just move the function declaration above setup(). Let me know how it goes
@peekay123, same error I’m afraid