I got some problem while working with arduino due.From what i know each timer channel has 3 compare registers,2 i/o lines (for A and B compares) and one Interrupt number.
Now is there a way to raise specific interrupt for A,B,C compares belonging to same channel?
I am confused as there is only one interrupt number attached to one channel while three events are happening(A compare ,B compare ,C compare) per channel.
Is there a way to select a particular procedure to be executed for a particular compare event.
(i.e. selection of a particular procedure under one interrupt number)
Note: I am working in 'Waveform Mode'.
Thanks in advance.
I recommend reading the following post where cmaglie details that each of the 9 possible interrupts (3 channels in each of the 3 timer counters) can generate a unique interrupt, independent of the others.
In the post there is a nice explanation and example of setting up the resources. Along with a table that details which parameter correspond to appropriate settings.
Related
I'm building a firmware for a device based on Atmel/Microchip AT SAMG55.
In a simple function, trigger some relais connected to GPIO pins.
Because I want to interlock different I/O, avoiding that 2 specific outputs are high level on the same time, I need to know the pin level I set before.
In another project, based on the SAMD21, there was a function that reads output pin state
static inline bool port_pin_get_output_level(const uint8_t gpio_pin)
The SAMG55 port library in ASF is quite different, so i tried ioport_get_pin_level(pin), but i'm not getting expected result. I think that it works only with pins configured as inputs.
Are there any recommended solutions?
Referring to Figure 16-2 in the SAMG55 data sheet, and to sections 16.5.4 and 16.5.8:
16.5.4 Output Control
... The level driven on an I/O line can be determined by writing in the Set Output Data Register (PIO_SODR) and
the Clear Output Data Register (PIO_CODR). These write operations,
respectively, set and clear the Output Data Status Register
(PIO_ODSR), which represents the data driven on the I/O lines. ...
16.5.8 Inputs
The level on each I/O line can be read through PIO_PDSR. This register indicates the level of the I/O lines regardless of their
configuration, whether uniquely as an input, or driven by the PIO
Controller, or driven by a peripheral. Reading the I/O line levels
requires the clock of the PIO Controller to be enabled, otherwise
PIO_PDSR reads the levels present on the I/O line at the time the
clock was disabled.
So, as long as the pin is configured such that the actual level on the pin always corresponds to the level we're trying to drive - which is not the case with an open collector configuration, for example - then Tarick Welling's answer is correct: you can read the output state from the Output Data Status Register (PIO_ODSR).
However the true state of the pin, regardless of driver configuration, can be read (subject to a resynchronisation delay that may or may not be relevant in any given application) from the Pin Data Status Register (PIO_PDSR).
You can do some low level programming. You use the high level HAL functions to configure, set and reset the pins but before you do that you would. Read the value for the pin by addressing the data value of the register. In AVR that would be done by reading PORTx. In a STM32 this can be done by reading the value of GPIOx->ODR. You would of course then need to extract the correct pin but this can be done.
You can also look inside the definition of port_pin_get_output_level and check how they did it and convert that into the way this board/vendor/HAL does its addressing.
update:
When looking inside the datasheet for the SAM G55G/J. Page 340 gives us the answer we need.
The level driven on an I/O line can be determined by writing in the Set Output Data Register (PIO_SODR) and the
Clear Output Data Register (PIO_CODR). These write operations, respectively, set and clear the Output Data
Status Register (PIO_ODSR), which represents the data driven on the I/O lines.
So we can drive the output by writing to PIO_SODR and PIO_CODR to set and reset the pins respectively. But also read from PIO_ODSR this is a register which contains the state of the pin.
A quick google search turns up two options for Atmel/AVR controllers:
read back from the same location you used to set your output value (PORTx register)
This will give you the value that you have written into the register before.
read the actual value using the PINx registers
This will give you the value that you could actually measure on your device.
The difference between the two can be important: if you set a GPIO that is pulled down below the logic voltage threshold (i.e. if connected to GND) to HIGH, PORTx will read HIGH (the value you set) while PINx will read LOW (the actual value).
https://www.avrfreaks.net/forum/reading-pin-set-output
I am trying to start a project in which I would create my own app on iOS using Swift to communicate with an Arduino 101 to control multiple LEDs. I have used this project as a base point.
After getting this to work with my custom app, I wanted to figure out how to make this work with multiple LEDs instead of just one. Currently, I am just performing writeCharacteristic to send a 1 or a 0 to the Arduino depending on which button I press (ON/OFF). However, for the new project, I need to be able to select one of the lights (select one of four output pins), and write a 1 or a 0 to turn it on and off. I didn't know what approach I should take to do this.
I don't need any code, just suggestions on how I can make this work through swift/Arduino code.
Thanks.
It's all explained in the manual.
https://www.arduino.cc/en/Reference/CurieBLE
Service design patterns
A characteristic value can be up to 20 bytes long. This is a key
constraint in designing services. Given this limit, you should
consider how best to store data about your sensors and actuators most
effectively for your application. The simplest design pattern is to
store one sensor or actuator value per characteristic, in ASCII
encoded values.
So either create a separate BLEBoolCharacteristic instance for each LED or combine the switch state of all leds in the same BLECharacteristic. For example you could encode 8 LED states in a single byte (1 LED per bit).
Do whatever you prefer. But read manuals...
I am using a PIC24 microcontroller and have multiple inputs. Via these I would like to obtain analog voltage data as fast as possible. I have 8 different data arriving to the microcontroller and I am a bit confused how to solve the problem.
My first idea was to to read in the data sequentially. First from AN0, then AN1 and so forth, but this may take quite a while and I am not at all sure it would be fast enough to do without any other trick. Especially because I do not only want to read in one single value per pin, but an array of voltages, then store and numerically integrate and send the results through USB to the PC. While doing so, new data should be constantly received via the aforementioned pins.
Is it feasible at all what I'm trying to achieve here?
Thanks in advance :)
You should think through your requirements a little more, especially the "at the same time" and "as fast as possible" statements. If you sample each channel within 10 to 100 microseconds of the next would that be satisfactory? What is the maximum frequency of the input signal that you need to detect? Your sampling frequency should be at least double the maximum signal frequency of interest.
Use a single ADC with enough input channels. Configure the ADC so that each time it is triggered to take a sample it will sample all of the channels in sequence (multichannel scan). It won't sample all 8 channels at literally "the same time", but it will cycle through each channel and sample them one after the other at nearly the same time. This could be within a few microseconds depending on the clock rate of the ADC and the channel setup time that you configure.
Now you could configure the ADC to sample in continuous mode where it would start the next sample scan immediately after finishing the previous scan. That would be "as fast as possible" but that might be faster than you need and produce more data than can be processed. Instead you should choose the sampling rate based upon the input signal frequency of interest and setup the ADC to sample at that rate. This rate might be much less than "as fast as possible". You might configure the ADC to collect one sample per channel when it is triggered (single conversion mode) and also setup a hardware timer to expire at the desired sampling rate and trigger the ADC to take a sample scan. The sample period (time between samples) must be greater than the time required to scan all the channels because you won't be able to trigger the ADC again before it has completed the previous channel scan.
If you really need to sample all channels at literally the same time then you probably need a separate ADC for each channel and then trigger all the ADCs to collect a sample at once.
I'm new to BLE and hope you will be able to point me towards the right implementation approach.
I'm working on an application in which the peripheral (battery operated) device continuously aggregate sensor readings.
On the mobile side application there will be a "sync" button, upon button press, I would like to transfer all the sensor readings that were accumulated in the peripheral to the mobile application.
The maximal duration between sync's can be several days, hence, the accumulated data can reach a size of 20Kbytes.
Now, I'm wondering what will be the best approach to perform the data transfer from the peripheral to the central application.
I thought about creating an array of characteristics where each characteristic will contain a fixed amount of samples (e.g. representing 1hour of readings).
Then, upon sync, I will:
Read the characteristics count (how many 1hours cells).
Then read the characteristics (1hour cells) one by one.
However, I have no idea if this is a valid approach ?
I'm not sure if this is the most "power efficient" way that I can
use.
I'm not sure if Characteristic READ is the way to go, or maybe
I need to use indication instead.
Any help here will be highly appreciated :)
Thanks in advance, Moti.
I would simply use notifications.
Use one characteristic which you write something to in order to trigger the transfer start.
Then have another characteristic which you simply stream data over by sending 20 bytes at a time. Most SDKs for BLE system-on-a-chips have some way to control the flow of data so you don't send too fast. Normally by having a callback triggered when it is ready to take the next notification.
In order to know the size of the data being sent, you can for example let the first notification contain the size, and rest of them the data.
This is the most time and power efficient way since there can be sent many notifications per connection interval, compared if you do a lot of reads instead which normally requires two round trips each. Don't use indications since they also require basically two round trips per indication. They're also quite useless anyway.
You could possibly increase the speed also by some % by exchanging a larger MTU (which leads to lower L2CAP/ATT headers overhead).
I want to find time difference between two pulses using PIC16F628.
I am using a 4MHz external oscillator, MikroC compiler.
As a simple example let's assume there is a push button. When we press it, it sends a high signal to a pin. We press this button twice with some delay in between, I want to find the time difference between these two button presses.
Thank you.
As mentioned in the comments, the simplest way to do this is to use a timer/counter combo. I found this quick tutorial on how to do this specifically for PIC: http://www.mikroe.com/chapters/view/17/chapter-4-examples/#c4v5.
Have a look at 4.5 and 4.6, they give you exactly the information you'll need to get the count of timer intervals between pulses. The basic technique is to start a timer, associate an interrupt handler (Read: function) with the timer, and then increment a counter everytime the interrupt handler is called. Next time you see the pulse, read what the counter value is.
After that, all you need to know is the timebase you've set the counter to (which will be some integer subdivision of your oscillator rate, and is selectable in code usually) and you can convert # of timer intervals to time in seconds/millis/nanos.