My ISR is executed only once even if I attempt to clear the Timer Flag - isr

I'm learning PIC32 and making some tests to make sure my ISRs are working properly. My test code is just turning a LED on and off in a time interval controlled by the ISR.
Problem is, the ISR executes only once, and I don't get why.
I've tried the actual code to turn the LED on and off in the main function, with a timer between the turning on and off, it's working fine.
I've tried different ways of clearing the interrupt flag to make sure it's cleared. but i can't say if it's actually ok or not.
here is the code
#include <p32xxxx.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <plib.h>
#include <xc.h>
#define PIN_bypassled PORTEbits.RE4
#define PIN_bypassledwrite LATEbits.LATE4
//-------- ISRs -----------------
//low speed timer
void __ISR( _TIMER_2_VECTOR, ipl7) Swiching_loop( void)
{
// INTDisableInterrupts();
mT2ClearIntFlag(); // first attempt to clear interrput flag
IFS0bits.T2IF = 0; // second attempt to clear interrupt flag
PIN_bypassledwrite = !PIN_bypassled;
// INTEnableInterrupts();
}
void main() {
TRISE = 0x000000;
SYSTEMConfigPerformance(80000000L); // INTEnableSystemSingleVectoredInt();
// T1CON = 0X0010; //TMR1 Off, PRESCALE 1:256, 16b mode
PR1 = 100000;
mT1SetIntPriority(7); //set priority interrupt level for timer 1
T1CON = 0x8030; //TMR1 ON, PRESCALE 1:256, 16b mode
mT1IntEnable(1); //
// T2CON = 0X0030; //TMR2 Off, PRESCALE 1:256, 16b mode
PR2 = 100000;
mT2SetIntPriority(7); //set priority interrupt level for timer 2
T2CON = 0x8070; //TMR2 ON, PRESCALE 1:256, 16b mode
mT2IntEnable(1); //
INTEnableInterrupts();
while (1){
}
}
expected result would be my LED turning on and off, but instead it's just turning on. I interpret this as the ISR only executing once, but maybe i'm missing something since i'm under the impression that i'm clearing the interrupt flag correctly.
What am i missing?

Related

How to implement ticker callback at 100 micro seconds for ESP8266?

I have an ESP8266 NodeMCU 12E development board and I'm using the Arduino IDE. I'm trying to use a Ticker.h to sample an analog input consistently at a frequency of 10khz, which is one sample every 100us. I noticed that Ticker sampler; sampler.attach(0.0001,callbackfunc); didn't work because attach() won't take the value 0.0001.
So then I wrote the following code based on some guides that I saw:
#include <ESP8266WiFi.h>
#include <Ticker.h>
bool s = true;
void getSample()
{
s = !s;
}
Ticker tickerObject(getSample, 100, 0, MICROS_MICROS);
const char *ssid = "___"; // Change it
const char *pass = "___"; // Change it
void setup()
{
Serial.begin(115200);
Serial.println(0); //start
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
tickerObject.start();
}
void loop()
{
if(s == true)
{
Serial.println("True");
}
else
{
Serial.println("False");
}
}
However, this did not compile because tickerObject.start() method did not exist. So what I did next was:
Download the latest ticker package as a zip file
Unzip the package from point 1
Made a back up of C:\Users\john\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\Ticker
Replaced the folder mentioned in point 3 with the Ticker folder in point 2.
Restarted my Arduino IDE
Compiled and ran the code
Opened up the Serial Monitor
However, when I inspect the serial monitor, all it prints is "True". I was expecting the value s to toggle between true and false at a 10khz frequency.
What did I do wrong?
From the documentation of this library:
The library use no interupts of the hardware timers and works with the micros() / millis() function.
This library implements timers in software by polling the micros() and millis() functions. It requires the update() method to be called in loop().
So the start of loop() should be:
void loop()
{
tickerObject.update();
if(s == true)
I'm trying to use a Ticker.h to sample an analog input consistently at a frequency of 10khz
It is worth a go but this is a software based solution that is prone to jitter depending on how often the event loop can be called.

Can't send data from my custom IOS App using BLE Shield 2.1 to my Arduino Uno

I am currently working on designing a snake-like robot that will be controlled via a custom Iphone iOS app.
I am using the following technologies:
- Arduino-Uno
- Adafruit Motor Shield
- Nema 17 Bipolar Stepper Motor
- BLE Shield 2.1 from RedBearLab
My iOS app includes a slider, such that when the slider moves, a stepper motors speed will be controlled. I am using a Write function in xcode to send the speed data to my arduino, but when I try to print the read results in my Serial Monitor, the data is just 0.
func writeSpeed(_ speed: UInt8)
{
// See if characteristic has been discovered before writing to it
if let positionCharacteristic = self.positionCharacteristic
{
let data = Data(bytes: [speed])
self.peripheral?.writeValue(data, for: positionCharacteristic, type: CBCharacteristicWriteType.withResponse) //with originally
print(data)
print(speed)
}
}
When I print the data and speed it's results look as follows...
1 bytes
3
1 bytes
4
1 bytes
3
1 bytes
2
end sliding
My Arduino code is as follows...
// Add in necessary libraries
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <boards.h>
#include <RBL_nRF8001.h>
#include <RBL_services.h>
SoftwareSerial BLE_Shield(9,8); // Configure the Serial port to be on pins D8 and D9. This
// will match the jumpers on the BLE Shield (RX -> D8 & TX /> D9)
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Define the stepper motor attached to the motor shield.
// i.e. 200 steps per revolution (1.8 degree) in motor port #2 (M3 and M4)
const int stepsPerRevolution = 200;
const int motorPort = 2;
Adafruit_StepperMotor *myMotor = AFMS.getStepper(stepsPerRevolution,
motorPort);
void setup()
{
// put your setup code here, to run once:
BLE_Shield.begin(9600); // Setup the serial port at 9600 bps. This is the BLE Shield default baud rate.
ble_begin();
// Initialize serial port at 9600 bps
Serial.begin(9600);
// Print a ready statement to serial monitor
Serial.println("Stepper Motor is Ready!");
// Stepper motor
AFMS.begin(1600); // create with the default frequency 1.6KHz
}
void loop()
{
// put your main code here, to run repeatedly:
ble_do_events();
if(BLE_Shield.available())
{
Serial.println("Available");
// Read the value of the slider and store it in the variable data
int data = BLE_Shield.read(); //Read the incoming data & store into data
Serial.println("The data from iphone is...");
Serial.print(data);
// Eventually sliderData will be a variable, but for now, a constant
const int sliderData = 30;
// Specify the speed of my stepper motor
myMotor->setSpeed(sliderData); // 30 rpm
Serial.println("Speed is 30 rpm");
}
else
{
Serial.println("Stopped working");
}
//ble_do_events();
delay(500);
}
I really don't know why this isn't working.

My first PIC32MX ISR not firing, code is hanging

I'm just getting started with a PIC32MX340F12, and MPLABX. My first attempt was to write a timer interrupt, so I worked with the datasheet, compiler manual, and examples and came up with the below. But it doesn't work... the interrupt never fires, and in fact if I leave both the timer interrupt enable (T1IE=1) and the general interrupt enable active ("ei"), it runs for a few seconds then hangs (says "target halted" in debug mode). If I remove either of those, it just runs indefinitely but still no timer interrupt. So I appear to have a pretty bad problem somewhere in my ISR syntax. Does it jump out at anyone?
Like I said I'm just getting started so I'm sure it's a pretty dumb oversight. And as you may notice I like to work as directly as possible with registers and compiler directives (rather than manufacturer supplied functions), I feel like I learn the most that way.
Thanks!
#include <stdio.h>
#include <stdlib.h>
#include "p32mx340f512h.h"
#include <stdint.h>
int x = 0;
int main(int argc, char** argv)
{
INTCONbits.MVEC = 1; // turn on multi-vector interrupts
T1CON = 0; // set timer control to 0
T1CONbits.TCKPS = 1; // set T1 prescaler to 8
PR1 = 62499; // set t1 period
TMR1 = 0; // initialize the timer
T1CONbits.ON = 1; // activate the timer
IPC1bits.T1IP = 5; // T1 priority to 5
IPC1bits.T1IS = 0; // T1 secondary priority to
IFS0bits.T1IF = 0; // clear the T1 flag
IEC0bits.T1IE = 1; // enable the T1 interrupts
asm volatile("ei"); // enable interrupts
while (1)
{
x++;
if (x > 10000)
{
x = 0;
}
}
return (EXIT_SUCCESS);
}
bool zzz = false;
void __attribute__((interrupt(IPL5AUTO))) T1Handler(void)
{
IFS0bits.T1IF = 0;
zzz = true;
}
Embedded systems are somewhat specialized, and this is a specific one I'm not familiar with.
However, from working with other systems, you may have to associate the Int Handler function address (T1Handler) with the interrupt it is handling. (Unless the framework you are using is doing that for you under the covers when building?)
Are all those names you are using automatically mapped for you by the build system?
If not, you may need to call some kind HW init or framework init at the top of main, before using them.
Some HW init/reset may be needed also, before the HW can be programmed.
Hope some of this helps.

Can NSLog be disabled from appearing in device's console? [duplicate]

This question already has answers here:
How do I disable NSLog?
(15 answers)
Closed 8 years ago.
I have a builded application that is running on device. I open device's console view in XCode's Organizer window. I assume (for the sake of this question) that NSLog(#"Some string") gets called.
Is there any way, may be an option in device, or application's settings, that would disable this log from appearing in console?
Edit: I'm not interested in replacing NSLog by other solution that can achieve this effect. The purpose of this question is to fully understand NSLog's functionality.
(Thanks to #MartinR for encouraging me to pull my finger out on this answer and to correctly identify that you cannot just close stdout/stderr, as the next open() will re-use those file descriptors, but to redirect stdout/stderr to the infamous /dev/null).
logControl.h:
#pragma once
extern void stopLogging();
extern void startLogging();
logControl.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static int loggingStopped = 0;
static int oldStdout = -1;
static int oldStderr = -1;
void stopLogging() {
if (!loggingStopped) {
oldStdout = dup(1);
oldStderr = dup(2);
int devNull = open("/dev/null", O_WRONLY);
dup2(devNull, 1);
dup2(devNull, 2);
close(devNull);
loggingStopped = 1;
}
}
void startLogging() {
if (loggingStopped && oldStdout >= 0 && oldStderr >= 0) {
dup2(oldStdout, 1);
close(oldStdout);
oldStdout = -1;
dup2(oldStderr, 2);
close(oldStderr);
oldStderr = -1;
loggingStopped = 0;
}
}
This works at runtime, not compile time, which I believe is what you are asking. Simply call stopLogging() or startLogging() as required.
NOTE: There is no error-checking to speak of, so that could be improved perhaps.
Add this line given below in your .pch file in Xcode.
#define NSLog(...)
It will disable all NSLogs.
for more alternatives see the link
#if TARGET_IPHONE_SIMULATOR
//Simulator
#else
// Device
#define NSLog
#endif
Add this in your .pch file this will disable NSLog only for device alone not for simulator.
Add below code to .pch file
#ifdef DEBUG
# define NSLog(...) NSLog(__VA_ARGS__)
#else
# define NSLog(...) /* */
#endif
And in Build Settings, search "Preprocessor Macros" and remove "DEBUG=1" written in it.
and Thats it, you will not see any logs in your console now.

iOS - Generate and play indefinite, simple audio (sine wave)

I'm looking to build an incredibly simple application for iOS with a button that starts and stops an audio signal. The signal is just going to be a sine wave, and it's going to check my model (an instance variable for the volume) throughout its playback and change its volume accordingly.
My difficulty has to do with the indefinite nature of the task. I understand how to build tables, fill them with data, respond to button presses, and so on; however, when it comes to just having something continue on indefinitely (in this case, a sound), I'm a little stuck! Any pointers would be terrific!
Thanks for reading.
Here's a bare-bones application which will play a generated frequency on-demand. You haven't specified whether to do iOS or OSX, so I've gone for OSX since it's slightly simpler (no messing with Audio Session Categories). If you need iOS, you'll be able to find out the missing bits by looking into Audio Session Category basics and swapping the Default Output audio unit for the RemoteIO audio unit.
Note that the intention of this is purely to demonstrate some Core Audio / Audio Unit basics. You'll probably want to look into the AUGraph API if you want to start getting more complex than this (also in the interest of providing a clean example, I'm not doing any error checking. Always do error checking when dealing with Core Audio).
You'll need to add the AudioToolbox and AudioUnit frameworks to your project to use this code.
#import <AudioToolbox/AudioToolbox.h>
#interface SWAppDelegate : NSObject <NSApplicationDelegate>
{
AudioUnit outputUnit;
double renderPhase;
}
#end
#implementation SWAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// First, we need to establish which Audio Unit we want.
// We start with its description, which is:
AudioComponentDescription outputUnitDescription = {
.componentType = kAudioUnitType_Output,
.componentSubType = kAudioUnitSubType_DefaultOutput,
.componentManufacturer = kAudioUnitManufacturer_Apple
};
// Next, we get the first (and only) component corresponding to that description
AudioComponent outputComponent = AudioComponentFindNext(NULL, &outputUnitDescription);
// Now we can create an instance of that component, which will create an
// instance of the Audio Unit we're looking for (the default output)
AudioComponentInstanceNew(outputComponent, &outputUnit);
AudioUnitInitialize(outputUnit);
// Next we'll tell the output unit what format our generated audio will
// be in. Generally speaking, you'll want to stick to sane formats, since
// the output unit won't accept every single possible stream format.
// Here, we're specifying floating point samples with a sample rate of
// 44100 Hz in mono (i.e. 1 channel)
AudioStreamBasicDescription ASBD = {
.mSampleRate = 44100,
.mFormatID = kAudioFormatLinearPCM,
.mFormatFlags = kAudioFormatFlagsNativeFloatPacked,
.mChannelsPerFrame = 1,
.mFramesPerPacket = 1,
.mBitsPerChannel = sizeof(Float32) * 8,
.mBytesPerPacket = sizeof(Float32),
.mBytesPerFrame = sizeof(Float32)
};
AudioUnitSetProperty(outputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&ASBD,
sizeof(ASBD));
// Next step is to tell our output unit which function we'd like it
// to call to get audio samples. We'll also pass in a context pointer,
// which can be a pointer to anything you need to maintain state between
// render callbacks. We only need to point to a double which represents
// the current phase of the sine wave we're creating.
AURenderCallbackStruct callbackInfo = {
.inputProc = SineWaveRenderCallback,
.inputProcRefCon = &renderPhase
};
AudioUnitSetProperty(outputUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));
// Here we're telling the output unit to start requesting audio samples
// from our render callback. This is the line of code that starts actually
// sending audio to your speakers.
AudioOutputUnitStart(outputUnit);
}
// This is our render callback. It will be called very frequently for short
// buffers of audio (512 samples per call on my machine).
OSStatus SineWaveRenderCallback(void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
// inRefCon is the context pointer we passed in earlier when setting the render callback
double currentPhase = *((double *)inRefCon);
// ioData is where we're supposed to put the audio samples we've created
Float32 * outputBuffer = (Float32 *)ioData->mBuffers[0].mData;
const double frequency = 440.;
const double phaseStep = (frequency / 44100.) * (M_PI * 2.);
for(int i = 0; i < inNumberFrames; i++) {
outputBuffer[i] = sin(currentPhase);
currentPhase += phaseStep;
}
// If we were doing stereo (or more), this would copy our sine wave samples
// to all of the remaining channels
for(int i = 1; i < ioData->mNumberBuffers; i++) {
memcpy(ioData->mBuffers[i].mData, outputBuffer, ioData->mBuffers[i].mDataByteSize);
}
// writing the current phase back to inRefCon so we can use it on the next call
*((double *)inRefCon) = currentPhase;
return noErr;
}
- (void)applicationWillTerminate:(NSNotification *)notification
{
AudioOutputUnitStop(outputUnit);
AudioUnitUninitialize(outputUnit);
AudioComponentInstanceDispose(outputUnit);
}
#end
You can call AudioOutputUnitStart() and AudioOutputUnitStop() at will to start/stop producing audio. If you want to dynamically change the frequency, you can pass in a pointer to a struct containing both the renderPhase double and another one representing the frequency you want.
Be careful in the render callback. It's called from a realtime thread (not from the same thread as your main run loop). Render callbacks are subject to some fairly strict time requirements, which means that there's many things you Should Not Do in your callback, such as:
Allocate memory
Wait on a mutex
Read from a file on disk
Objective-C messaging (Yes, seriously.)
Note that this is not the only way to do this. I've only demonstrated it this way since you've tagged this core-audio. If you don't need to change the frequency you can just use the AVAudioPlayer with a pre-made sound file containing your sine wave.
There's also Novocaine, which hides a lot of this verbosity from you. You could also look into the Audio Queue API, which works fairly similar to the Core Audio sample I wrote but decouples you from the hardware a little more (i.e. it's less strict about how you behave in your render callback).

Resources