Show Posts
Pages: 1 [2] 3 4 ... 36
16  Using Arduino / Programming Questions / Re: Enabling pin change interrupt on Attiny84 on: January 30, 2014, 04:01:42 pm
Is this the way it should look like:
Code:
 PCMSK0 = bit (PCINT1) | bit (PCINT2);
  GIMSK  = bit (PCIE0);  

If you are going to access lots of registers, not use Arduino functions etc, personally I'd say you're better off writing code in Atmel Studio without the Arduino framework. (As the IDE will finish register bit names for you etc...)

What you would do is include <stdio.h> and set GIMSK |= (1 << PCIE0)
17  Using Arduino / Programming Questions / Re: Enabling pin change interrupt on Attiny84 on: January 30, 2014, 03:59:21 pm
Depends - always read the datasheet, sometimes yes, sometimes no. As far as I'm aware, in all AVR devices the interrupt flags are cleared by writing a one.
18  Using Arduino / Programming Questions / Re: Enabling pin change interrupt on Attiny84 on: January 30, 2014, 03:51:23 pm
No, as Coding Badly says, those flags are cleared by writing a logical one to them (or by the ISR being called, I believe).
19  Using Arduino / Programming Questions / Re: Enabling pin change interrupt on Attiny84 on: January 30, 2014, 03:43:25 pm
...further to our replies - you are accessing the correct registers to achieve what you want, yes - but you should set the required bits with an OR bit mask, as you are also setting all the other bits to 0 (which you or may not be a problem for you). As your code grows, you'll need to set just one bit in a register without affecting the others.

Google 'avr bit manipulation 101'.
20  Using Arduino / Programming Questions / Re: Enabling pin change interrupt on Attiny84 on: January 30, 2014, 03:32:23 pm
Note for future,  instead of setting SREG directly, global interrupts can be enabled by calling

Code:
sei();

And disabled by

Code:
cli();

21  Using Arduino / Programming Questions / Re: PID code for controlling speed dc motor. on: January 30, 2014, 03:16:41 pm
If it helps, here's a piece of code I wrote AGES ago using the same PID library, it was to control a FBW throttle using a manual pot in a completely non safety critical application, and was nothing more than a bare bones functional of the motor driving hardware that later on went to see use in a project with C code written in Atmel Studio on a custom controller.

Code:
#include <PID_v1.h>

const int pwm_pin = 6;
const int in_a_pin = 5;
const int in_b_pin = 4;
const int en_a_pin = 9;
const int en_b_pin = 7;
const int current_sense_pin = A0;

const int pps_pin = A3;
const int tps1_pin = A1;
const int tps2_pin = A2;

double duty_cycle = 0;
double current_reading = 0;
double pps = 0;
double tps1 = 0;
double tps2 = 0;
double tps_sum = 0;

float current = 0;

PID throttle_PID(&tps1, &duty_cycle, &pps, 2, 0, 0, 0); // last zero is there, because direction is set in loop

void setup()
{
  Serial.begin(115200);

  pinMode(pwm_pin, OUTPUT);
  pinMode(in_a_pin, OUTPUT);
  pinMode(in_b_pin, OUTPUT);
  pinMode(en_a_pin, INPUT);
  pinMode(en_b_pin, INPUT);
  pinMode(current_sense_pin, INPUT);

  digitalWrite(in_a_pin, LOW);
  digitalWrite(in_b_pin, LOW);

  throttle_PID.SetMode(AUTOMATIC);
  throttle_PID.SetSampleTime(5);
  throttle_PID.SetOutputLimits(0, 255);

  TCCR0B = TCCR0B & 0b11111000 | 0x03; // set pwm to 976Hz
}

void loop()
{
  tps1 = analogRead(tps1_pin);
  // tps2 = analogRead(tps2_pin);
  // tps_sum = tps1 + tps2;

  // Serial.println(tps1);
  // Serial.println(tps2);

  pps = analogRead(pps_pin);
  // pps = map(pps, 0, 1023, 150, 980);
  // Serial.println(pps);

  if (pps >= tps1)
  {
    digitalWrite(in_a_pin, HIGH);
    digitalWrite(in_b_pin, LOW);

    throttle_PID.SetControllerDirection(DIRECT);

    throttle_PID.Compute();
    analogWrite(pwm_pin, duty_cycle);
  }

  if (pps <= tps1)
  {
    digitalWrite(in_a_pin, LOW);
    digitalWrite(in_b_pin, HIGH);

    throttle_PID.SetControllerDirection(REVERSE);

    throttle_PID.Compute();
    analogWrite(pwm_pin, duty_cycle);
  }

 /*if (pps >= 155 <= 165 && tps1 >= 170 <= 180)
  {
    digitalWrite(in_a_pin, LOW);
    digitalWrite(in_b_pin, LOW);
    analogWrite(pwm_pin, 0);
  }*/

  // current_reading = analogRead(current_sense_pin);
  // Serial.println(current_reading);
}

22  Using Arduino / Programming Questions / Re: Digital low pass filter on: January 30, 2014, 02:54:35 pm
Thanks Pito,

I've got an analog discovery, which has a built in programmable function generator so I'll test some up tomorrow with some frequency sweeps and see what happens.

Are the 'taps', what is commonly referred to by most sources as the filter coefficients?
23  Using Arduino / Programming Questions / Re: Digital low pass filter on: January 30, 2014, 11:29:16 am
Yes, phase linearity is something that's important. So, the filter designed here - http://t-filter.appspot.com/fir/index.html

Is that a butterworth filter?
24  Using Arduino / Programming Questions / Re: Digital low pass filter on: January 30, 2014, 11:13:45 am
I got as far as generating what you have in that example using my required numbers before - but I don't understand the long list of taps?

I also don't understand if I need an IIR or FIR filter etc - these are all things I need to look up...
25  Using Arduino / Programming Questions / Re: Digital low pass filter on: January 30, 2014, 10:59:32 am
Hmm - thanks for the links, seems like I need to do some more reading, IIRs vs FIRs etc...  smiley-confuse
26  Using Arduino / Programming Questions / Digital low pass filter on: January 30, 2014, 08:02:24 am
Hi all,

I'm revisiting a project of mine, the PCBs are done already - so i'm limited to software only.

I'm filtering the output of some accelerometers with a simple first order RC filter, with my cut off frequency at 100Hz, and being first order I've only got 20dB/decade of gain in the stopband. The ADC sampling frequency is 600Hz, so no aliasing issues there.

However, I'd like really to have more like 40dB/decade, therefore adding a software 1st order low pass filter will give me total 40dB/decade of roll off.

I don't want to move my -3dB point to less than 100Hz.

Cheers!

EDIT - I'm using this tool (http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html) but when I test it in Excel with some generic data, it doesn't filter per se - just reduces the amplitude, even if the input is within the passband. Clearly something fundamental I'm missing.

Additionally, the above clearly uses floating point math - whereas I'd like to stay integer... there must be a way to do this.
27  Using Arduino / Microcontrollers / Creating an entry for mega1284P-MU on: January 15, 2014, 08:46:15 am
Hi all,

I've used the Mighty 1284P files in the past with good success, however - I'm working on a device with a 1284P-MU, the 44pin QFN version. It has a few more GP IO pins and is mapped different in terms of pin numbers, so clearly I need to play with some files.

Here's the full pins file for the might 1284p with a 'standard' pinout.

Code:
#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include <avr/pgmspace.h>

// ATMEL ATMEGA1284P

/*
   PCINT15-8: D7-0  : bit 1
   PCINT31-24: D15-8  : bit 3
   PCINT23-16: D23-16 : bit 2
   PCINT7-0: D31-24   : bit 0
   */

#define NUM_DIGITAL_PINS            31
#define NUM_ANALOG_INPUTS           8
#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? (p) + 24 : -1)

#define digitalPinHasPWM(p)         ((p) == 3 || (p) == 4 || (p) == 6 || (p) == 7 || (p) == 12 || (p) == 13 || (p) == 14 || (p) == 15)

static const uint8_t SS   = 4;
static const uint8_t MOSI = 5;
static const uint8_t MISO = 6;
static const uint8_t SCK  = 7;

static const uint8_t SDA = 17;
static const uint8_t SCL = 16;
static const uint8_t LED = 7;

static const uint8_t A0 = 24;
static const uint8_t A1 = 25;
static const uint8_t A2 = 26;
static const uint8_t A3 = 27;
static const uint8_t A4 = 28;
static const uint8_t A5 = 29;
static const uint8_t A6 = 30;
static const uint8_t A7 = 31;

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 1 : (((p) <= 15) ? 3 : (((p) <= 23) ? 2 : 0)))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) ((p) % 8)

#ifdef ARDUINO_MAIN

#define PA 1
#define PB 2
#define PC 3
#define PD 4

// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
NOT_A_PORT,
(uint16_t) &DDRA,
(uint16_t) &DDRB,
(uint16_t) &DDRC,
(uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
NOT_A_PORT,
(uint16_t) &PORTA,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
NOT_A_PORT,
(uint16_t) &PINA,
(uint16_t) &PINB,
(uint16_t) &PINC,
(uint16_t) &PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
PB, /* 0 */
PB,
PB,
PB,
PB,
PB,
PB,
PB,
PD, /* 8 */
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PC, /* 16 */
PC,
PC,
PC,
PC,
PC,
   PC,
PC,
PA, /* 24 */
PA,
PA,
PA,
PA,
PA,
PA,
PA  /* 31 */
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
_BV(0), /* 0, port B */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 8, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 16, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 24, port A */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7)
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
NOT_ON_TIMER, /* 0  - PB0 */
NOT_ON_TIMER, /* 1  - PB1 */
NOT_ON_TIMER, /* 2  - PB2 */
TIMER0A,     /* 3  - PB3 */
TIMER0B, /* 4  - PB4 */
NOT_ON_TIMER, /* 5  - PB5 */
TIMER3A, /* 6  - PB6 */
TIMER3B, /* 7  - PB7 */
NOT_ON_TIMER, /* 8  - PD0 */
NOT_ON_TIMER, /* 9  - PD1 */
NOT_ON_TIMER, /* 10 - PD2 */
NOT_ON_TIMER, /* 11 - PD3 */
TIMER1B,     /* 12 - PD4 */
TIMER1A,     /* 13 - PD5 */
TIMER2B,     /* 14 - PD6 */
TIMER2A,     /* 15 - PD7 */
NOT_ON_TIMER, /* 16 - PC0 */
NOT_ON_TIMER,   /* 17 - PC1 */
NOT_ON_TIMER,   /* 18 - PC2 */
NOT_ON_TIMER,   /* 19 - PC3 */
NOT_ON_TIMER,   /* 20 - PC4 */
NOT_ON_TIMER,   /* 21 - PC5 */
NOT_ON_TIMER,   /* 22 - PC6 */
NOT_ON_TIMER,   /* 23 - PC7 */
NOT_ON_TIMER,   /* 24 - PA0 */
NOT_ON_TIMER,   /* 25 - PA1 */
NOT_ON_TIMER,   /* 26 - PA2 */
NOT_ON_TIMER,   /* 27 - PA3 */
NOT_ON_TIMER,   /* 28 - PA4 */
NOT_ON_TIMER,   /* 29 - PA5 */
NOT_ON_TIMER,   /* 30 - PA6 */
NOT_ON_TIMER   /* 31 - PA7 */
};

#endif // ARDUINO_MAIN

#endif // Pins_Arduino_h
// vim:ai:cin:sts=2 sw=2 ft=cpp

Personally, with my new pin mapping, I'd much rather just map pin numbers to physical pin numbers - and remove the extra layer of abstraction, as the package is not a DIP package on a breadboard, so it's of little help to number them any other way.

Assigning the SPI, I2C and analog pins is trivial, but what about the "static const uint8_t LED = 7;" line, LED - what LED?

No idea what these are doing...

Code:
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
[u] NOT_A_PORT,
(uint16_t) &DDRA,
(uint16_t) &DDRB,
(uint16_t) &DDRC,
(uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
NOT_A_PORT,
(uint16_t) &PORTA,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
NOT_A_PORT,
(uint16_t) &PINA,
(uint16_t) &PINB,
(uint16_t) &PINC,
(uint16_t) &PIND,
};

These surely assign which pins are part of which port?

Code:
const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
PB, /* 0 */
PB,
PB,
PB,
PB,
PB,
PB,
PB,
PD, /* 8 */
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PC, /* 16 */
PC,
PC,
PC,
PC,
PC,
   PC,
PC,
PA, /* 24 */
PA,
PA,
PA,
PA,
PA,
PA,
PA  /* 31 */
};
These lines must shift the pin numbers in to each port name - why?

Code:
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
_BV(0), /* 0, port B */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 8, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 16, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 24, port A */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7)
};

These lines clearly assign  which pin is on a timer, and which pin is not.

Code:
const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
NOT_ON_TIMER, /* 0  - PB0 */
NOT_ON_TIMER, /* 1  - PB1 */
NOT_ON_TIMER, /* 2  - PB2 */
TIMER0A,     /* 3  - PB3 */
TIMER0B, /* 4  - PB4 */
NOT_ON_TIMER, /* 5  - PB5 */
TIMER3A, /* 6  - PB6 */
TIMER3B, /* 7  - PB7 */
NOT_ON_TIMER, /* 8  - PD0 */
NOT_ON_TIMER, /* 9  - PD1 */
NOT_ON_TIMER, /* 10 - PD2 */
NOT_ON_TIMER, /* 11 - PD3 */
TIMER1B,     /* 12 - PD4 */
TIMER1A,     /* 13 - PD5 */
TIMER2B,     /* 14 - PD6 */
TIMER2A,     /* 15 - PD7 */
NOT_ON_TIMER, /* 16 - PC0 */
NOT_ON_TIMER,   /* 17 - PC1 */
NOT_ON_TIMER,   /* 18 - PC2 */
NOT_ON_TIMER,   /* 19 - PC3 */
NOT_ON_TIMER,   /* 20 - PC4 */
NOT_ON_TIMER,   /* 21 - PC5 */
NOT_ON_TIMER,   /* 22 - PC6 */
NOT_ON_TIMER,   /* 23 - PC7 */
NOT_ON_TIMER,   /* 24 - PA0 */
NOT_ON_TIMER,   /* 25 - PA1 */
NOT_ON_TIMER,   /* 26 - PA2 */
NOT_ON_TIMER,   /* 27 - PA3 */
NOT_ON_TIMER,   /* 28 - PA4 */
NOT_ON_TIMER,   /* 29 - PA5 */
NOT_ON_TIMER,   /* 30 - PA6 */
NOT_ON_TIMER   /* 31 - PA7 */

What about these remaining lines - it looks like digitalPinHasPWM is the digital pin number that is associated with an output compare channel? What about the very last line in the below code snippet?

Code:
[u]#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? (p) + 24 : -1)[/u]

#define digitalPinHasPWM(p)         ((p) == 3 || (p) == 4 || (p) == 6 || (p) == 7 || (p) == 12 || (p) == 13 || (p) == 14 || (p) == 15)

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 1 : (((p) <= 15) ? 3 : (((p) <= 23) ? 2 : 0)))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) ((p) % 8)[/u]

// vim:ai:cin:sts=2 sw=2 ft=cpp

The device will also have a different device signature, which I presume I will need to change in the avrdude boards conf file - what else should I be looking at changing?

Many thanks in advance!
28  Using Arduino / General Electronics / Re: Potting KEMET Supercapcitors (Perhaps JamesC4S can chime in here?) on: December 30, 2013, 04:03:19 pm
If you would have a few spare moments to ask the question, it would be a great help. Whilst these caps arn't being evaluated for a mass production product, we are looking at using these in quantity batches of ~100s at a time.

Ideally, I'd like to stay away from the FM series - as they don't appear to be regularly stocked at the usual suppliers. The FC caps are ideal for us, being an SMD package - so if there is a set of conditions that will allow us to pot these, great. If not, we can always pot up to a certain level, avoiding the caps.

However, the datasheet also states a guideline 500uA power supply under typical applications, is this the guideline current the supercap is designed to deliver during backup? I need to supply ~5-6mA for 20s or so... The product selector states the FT series being more suitable for ~5mA hold-up currents, which could be made to work with a slight board change. However, these still cannot be readily potted it would appear, although I still wish to be able to...

In terms of derating supercaps, what sort of percentages should be aimed for? There seems to be much less documentation floating about for EDLCs than many other caps. Is a 10-15% voltage derate appropriate at an ambient of ~40degC?

Quote
Yes, I do.  However, all of my forum posts are my personal opinions, not officially from KEMET.  If you want an "official" response, send a message through the kemet.com web site...  (Which, would probably end up coming to me anyway.)

In my experience, personal opinions can often be somewhat closer to reality than those that have been passed through 'official' channels, so i'll take your opinion...

Many, many thanks,
29  Using Arduino / General Electronics / Re: Potting KEMET Supercapcitors (Perhaps JamesC4S can chime in here?) on: December 30, 2013, 01:08:29 pm
The manufacturer will know, we can only guess.

That's the plan - JamesC4S on these forums works at KEMET I believe.
30  Using Arduino / General Electronics / Re: Potting KEMET Supercapcitors (Perhaps JamesC4S can chime in here?) on: December 30, 2013, 04:55:27 am
But, both types? I understand why almost all bulk caps cannot be potted, but why may the FM series be potted?
Pages: 1 [2] 3 4 ... 36