Show Posts
Pages: [1] 2 3 ... 440
1  Using Arduino / Sensors / Re: Interrupt problem with hall effect sensor on: July 10, 2014, 04:29:58 pm
When using a LM393 or other comparator to convert an analog input signal to a digital one, you almost always need to add hysteresis (positive feedback) to get clean digital transitions on the output. Digital Hall sensors don't need to be used with a comparator, and they have hysteresis built-in.
2  Topics / Science and Measurement / Re: Need 24 channel isolated ADC inputs? on: June 19, 2014, 05:20:54 pm
I know that this thread has been around for a while but ... There are some very neat hall effect current sensors which could solve your isolation issues.  Put a resistor in series to measure battery voltage, with completely isolated sense to output.

Nice idea; however the Hall current sensors I have come across are only reasonably accurate at currents of several amperes and higher, which would be too much drain on the battery.
3  Using Arduino / Microcontrollers / Re: Bot Interrupt Pins quit working. on: May 19, 2014, 10:23:13 am
There is a lot of discussion here, but there is one glaring error in all of this: variables used inside an interrupt routines have to be listed as "volatile" or the compiler will optimize them out of your sketch at compile time. By listing a variable as volatile, the compiler is notified that, even though variable doesn't seem to be used in the main part of the sketch, it will be used sometime, so it records it as an usable variable. Of course, that "sometime" is when an interrupt occurs.

It's not as simple as that. "volatile" tells the compiler that the variable may be modified in ways that the compiler is unaware of. This can happen for either of two reasons. The "variable" may in reality be a memory-mapped I/O port, so external events and/or reading the "variable" may change its value. Or the variable may be a true software variable, but one that is modified in an interrupt service routine and read in the main program, or modified by one thread and read by another in a multi-threaded environment.

Unless you are running a pre-emptive RTOS on your Arduino, then multi-threading does not apply. If you use direct port access, then the "volatile" qualifier is already taken care of for you, assuming you use the port definitions provided. So you only need to worry about variables used in ISRs. The general rules are:

1. Qualifying a variable does no harm except that it may slow down the program a little, and if you take the address of the variable then any pointer that you assign that address to also needs to be declared volatile.

2. Variables used solely in one interrupt service routine do not need to be declared volatile. Variables that are modified by the main program and read in ISRs do not need to be declared volatile.

3. Variables that are modified in an ISR and read in the main program should be declared volatile. If you fail to declare them volatile, then the program may still work - it depends on the nature of the program (e.g. if you read such a variable at most once each time loop() is called, then you will get away with not declaring it volatile). But the safe thing is to declare them volatile.
4  Using Arduino / Displays / Re: Graphical LCD (ST7920 Driver) - a warning and a question on: May 18, 2014, 04:58:57 am
I know of only two Arduino libraries for ST7920-based displays. The first is the u8glib library that you are currently using. The second is a library that I wrote for a particular application. You can find it find at https://github.com/dc42/arduino/tree/master/Libraries/Lcd7920 along with a simple sketch that uses it. It's less comprehensive than u8glib, and it uses up 1K of memory as an image buffer. I don't know whether you would find it any easier to use than u8glib.
5  Using Arduino / Displays / Re: Graphical LCD (ST7920 Driver) - a warning and a question on: May 15, 2014, 03:05:30 am
So your LCD already includes a series resistor for the backlight (the 33 ohms that you measured). It also has the contrast adjustment pot built-in. You are probably right about JP2, you can either solder a jumper there or you can connect the PSB pin on the edge connector to +5V or ground to select serial or parallel mode. But I suggest you trace that wire from the jumper middle pad to the PSB pin on the edge connector, to make sure that it isn't already connected to +5V or ground through a 0 ohm resistor, as was reported by someone else using a similar GLCD recently.

EDIT: I can't see any 0 ohm resistors in that photo, so I think you are safe.
6  Using Arduino / Project Guidance / Re: Measure of frequency on: May 04, 2014, 06:01:42 pm
Depending on the range of frequencies you want to measure, this one http://forum.arduino.cc/index.php?topic=64219.msg1433217#msg1433217 that I use may do the job.
7  Using Arduino / Project Guidance / Re: Anyone have a 3d printer? on: May 04, 2014, 05:54:14 pm
I have a RepRapPro Ormerod, which is sold in kit form by RS Components for just under £500 (+VAT where applicable). I'm fairly happy with it, although I have made major changes to the firmware (btw the electronics is based on the Arduino Due), replaced a few acrylic and MDF parts by aluminium, and replaced the original unmodulated IR height sensor by a combined modulated IR + ultrasonic one (and I have sold around 50 of these to other Ormerod users).

Printing large parts with a 3D printer is slow, and therefore expensive in machine time. 3D printers are great for prototyping and for small production runs, but for a large production run (hundreds or thousands of copies), you will want to use injection moulding.
8  Using Arduino / Microcontrollers / Re: Attiny 45 38khz flash on: April 11, 2014, 04:50:45 pm
Analog pin 4 does not support PWM, so you can't use the hardware timer/counters to generate a signal on that pin directly.
9  Using Arduino / Sensors / Re: Ultrasonic Parking Sensor Help on: March 11, 2014, 08:04:37 pm
For 1m range I think a ping sensor such as HC-SR04 would probably be sufficient and much easier than what I am doing. My application is really an ultrasonic modem. I was only bouncing the signal off the ceiling because that was a convenient way of testing it.
10  Using Arduino / Microcontrollers / Re: Bot Interrupt Pins quit working. on: March 11, 2014, 07:46:00 pm
polling is not really energy efficient, you're doing stuff that can be done in hardware with software.

There is nothing at all wrong with doing in software what can be done in hardware, that is what microcontrollers are all about. If the mcu is running at full power anyway then energy efficiency doesn't come into it. I've already said that I use an interrupt where I want to wake up the mcu from power down mode.
11  Using Arduino / Microcontrollers / Re: Bot Interrupt Pins quit working. on: March 11, 2014, 03:41:48 am
I think it's a bad idea to detach/attach interrupts inside the ISR. You won't get nested interrupts anyway unless you re-enable interrupts inside the ISR, and doing that is best avoided. A more professional solution to the problem you are trying to solve is to use an edge-triggered interrupt (i.e. mode FALLING instead of LOW), and to record the time at which the interrupt occurred. You can do this by calling micros() within the ISR and storing the returned value. Then in the ISR you can do nothing if not enough time has elapsed since the last interrupt. I agree that in simple systems with very little else going on (e.g. no serial I/O), calling delayMicroseconds inside the ISR may be an inelegant but simple way of debouncing.

However, it is generally simpler to handle pushbuttons by polling, except in the case where the button is used to wake up the mcu from power down mode. In that case, I use the interrupt only to wake up the mcu, and poll it the rest of the time.
12  Using Arduino / Sensors / Re: TCRT1000 sensor... i really need help. on: March 08, 2014, 02:36:22 pm
plz help me the circuit posted by the guy is not working.giving lot of noise  smiley-lol

That is nowhere near enough information. What is your application, what is the material that you are reflecting the IR from, and what is the distance between the TCRT1000 and the material you are trying to detect?

The schematic published earlier in this thread is suitable for detecting at quite long distances, but only if the system is well-shielded from sunlight and incandescent artificial light (otherwise the detector will saturate). For detection at shorter ranges, ditch the op amp, reduce the detector load resistor to about 3K3, and feed the detector output directly into an ADC pin.
13  Using Arduino / Microcontrollers / Re: Attiny 45 38khz flash on: February 20, 2014, 04:29:03 am
In case it helps, here is code I am using to turn 3 devices on or off when a button is pressed. I build it in AVR Studio, so it doesn't use the Arduino libraries (although I borrowed some code from them), and I use the internal 8MHz oscillator.

Code:
/*
 * RemoteControl.cpp
 *
 * Created: 25/11/2012 12:41:35
 *  Author: David
 */


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define F_CPU (8000000UL) // 8MHz

// Class to hold the data for the IR on/off signal for a particular device
class RemoteData
{
uint16_t headerMarkLength;
uint16_t headerNormalLength;
uint16_t headerRepLength;
uint16_t frequency;
uint16_t bitLength;
uint16_t bitPeriod;
uint32_t burstPeriod;
uint8_t numRepeats;
uint8_t numCycles;
const uint8_t *normalData;
const uint8_t *repeatData;

void generateBurst(bool isRepeat) const;

public:
RemoteData(uint16_t hml, uint16_t hnl, uint16_t hrl, uint16_t f, uint16_t bl, uint16_t bp, uint32_t up,
uint8_t nr, uint8_t nc, const uint8_t* nd, const uint8_t* rd)
: headerMarkLength(hml), headerNormalLength(hnl), headerRepLength(hrl), frequency(f), bitLength(bl), bitPeriod(bp), burstPeriod(up),
numRepeats(nr), numCycles(nc), normalData(nd), repeatData(rd)
{ }

void activate() const;
};

// Data for PVR on/off signal
const uint8_t pvrNormalData[] = {0b11111111, 0b11111011, 0b11111111, 0b11010101, 0b01010101, 0b01000000, 0};
const uint8_t pvrRepeatData[] = {0b10000000, 0};

const RemoteData pvr(9000, 13500, 11100, 38000, 555, 1110, 108000UL, 2, 1, pvrNormalData, pvrRepeatData);

// Data for TV on/off signal
const uint8_t tvNormalData[] = {0b10111111, 0b01011011, 0b11011000, 0};
const uint8_t tvRepeatData[] = {0b10111110, 0b01110110, 0b10101101, 0};

const RemoteData tv(0, 0, 0, 38000, 250, 1060, 66200UL, 1, 3, tvNormalData, tvRepeatData);

// Data for hifi on/off signal
const uint8_t hifiNormalData[] = {0b11110111, 0b01111111, 0b01010110, 0b10110101, 0b01010101, 0b11011111, 0b10101101, 0b01010101, 0};
const uint8_t hifiRepeatData[] = {0b10000000, 0};

const RemoteData hifi(9000, 13500, 13500, 38000, 555, 1120, 108000UL, 2, 1, hifiNormalData, hifiRepeatData);

// Set the frequency that we will get on pin OCR1A but don't turn it on
void setFrequency(uint16_t freq)
{
  uint32_t requiredDivisor = (F_CPU/2)/(uint32_t)freq;

  uint16_t prescalerVal = 1;
  uint8_t prescalerBits = 1;
  while ((requiredDivisor + prescalerVal/2)/prescalerVal > 256)
  {
    ++prescalerBits;
    prescalerVal <<= 1;
  }
  
  uint8_t top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
  TCCR1 = (1 << CTC1) | prescalerBits;
  GTCCR = 0;
  OCR1C = top;
}

// Turn the frequency on
void on()
{
  TCNT1 = 0;
  TCCR1 |= (1 << COM1A0);
}

// Turn the frequency off and turn off the IR LED.
// We let the counter continue running, we just turn off the OCR1A pin.
void off()
{
  TCCR1 &= ~(1 << COM1A0);
}

volatile uint32_t timer0_overflow_count = 0; // microseconds timer

// ISR for timer 0, counts microseconds
ISR(TIMER0_OVF_vect)
{
timer0_overflow_count++;
//TIFR |= _BV(TOV0);
}

// ISR for INT0, wakes up from sleep mode when button is pressed
ISR(INT0_vect)
{
GIMSK = 0; // disable INT0
}

// Return the number of microseconds from start
uint32_t micros()
{
uint8_t oldSREG = SREG;
cli();
uint32_t m = timer0_overflow_count;
uint8_t t = TCNT0;

if ((TIFR & (1 << TOV0)) && (t < 255))
{
m++;
}
SREG = oldSREG;

return (m << 8) | t;
}

void RemoteData::generateBurst(bool repeat) const
{
  setFrequency(frequency);
  uint32_t start = micros();
  if (headerMarkLength != 0)
  {
    on();
    while (micros() - start < headerMarkLength) {}
    off();
    uint32_t headerLength = repeat ? headerRepLength : headerNormalLength;
    while (micros() - start < headerLength) {}
  }

  const uint8_t* p = (repeat ? repeatData : normalData);
  uint32_t bitStart = micros();
  for(;;)
  {
    uint8_t b = *p++;
    if (b == 0) break;
    for (uint8_t i = 0; i < 8; ++i)
    {
      if (b & 0x80)
      {
        on();
        while (micros() - bitStart < bitLength) {}
        off();
      }
      while (micros() - bitStart < bitPeriod) {}
      b <<= 1;
      bitStart += bitPeriod;
    }
  }
  while (micros() - start < burstPeriod) {};
}

void RemoteData::activate() const
{
  for (uint8_t c = 0; c < numCycles; ++c)
  {
    generateBurst(false);
    for (uint8_t i = 0; i < numRepeats; ++i)
    {
      generateBurst(true);
    }
  }
}

void setup()
{
PORTB = 0b00011100; // pullup resistor on PB2/3/4 enabled, outputs PB0 and PB1 low
DDRB =  0b00000011; // PB0 and PB1 are outputs, rest are inputs

TCCR0A = 0;
TCCR0B = _BV(CS01); // prescaler = 8 so 1MHz count rate

TIMSK = _BV(TOIE0); // enable timer 0 overflow interrupt
GIMSK = 0;
PCMSK = 0;
}

int main(void)
{
setup();
sei();
for (uint8_t i = 0; i < 6; ++i)
{
uint32_t start = micros();
PORTB ^= 0b00000001; // toggle visible LED
while (micros() - start < 250000UL) {} // wait 0.25 secs before toggling it again
}

    for (;;)
    {
// Wait for button to be pressed
do
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cli();
if (PINB & 0b00000100)
{
GIMSK = _BV(INT0);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
sei();
uint32_t now = micros();
while ((micros() - now) < 5000) {}
} while (PINB & 0b00000100);

PORTB |= 0b00000001; // turn on visible LED
uint32_t start = micros();

// The TV doesn't always respond to the PVR HDMI signal up unless we activate it a short while before the PVR. So start the TV first and PVR last.
tv.activate();
while (micros() - start < 250000UL) {} // wait until 200ms after we started
hifi.activate();
while (micros() - start < 500000UL) {} // wait until 500ms after we started
pvr.activate();

while (micros() - start < 1000000UL) {} // keep LED on for at least a second

PORTB &= 0b11111110; // turn LED off

// Wait for button to be released
start = micros();
for (;;)
{
uint32_t now = micros();
if (!(PINB & 0b00000100))
{
start = now;
}
else if (now - start >= 5000)
{
break;
}
}
    }
}
14  Using Arduino / General Electronics / Re: NPN transistor switching on: February 20, 2014, 03:03:08 am
Glad you got it working. It sounds to me that the output driver on that pin has failed and only the internal pullup resistor is working (just as if you hadn't made the pinMode call).
15  Using Arduino / Microcontrollers / Re: Attiny 45 38khz flash on: February 20, 2014, 03:01:11 am
So have you programmed the fuses in the attiny to use the external crystal and clear the CLKDIV8 fuse?

I normally use the 8MHz internal clock on the attiny. The frequency doesn't need to be precise for 38kHz IR.
Pages: [1] 2 3 ... 440