Arduino timer seems to be crashing? - timer

For an exhibition with some interactive installations, I have to create a system that reads data from three ultrasonic PING sensors and has a DMX dimmer connected at one output.
So I took my Arduino Mega board, built some hardware around it (signal inverter for DMX) and tested the DMX dimmer using the library DmXSimple. It works fine!
Next step: testing the PING sensors. I used the library NewPing, and connected the sensors. It works fine!
Now both together, in one program: Importing both libraries, using the same codes. It doesn't work!
Timer collision? Well...anyway - I have no idea on how to solve that. What should I do? If it's a timer issue (that is, both libraries call the same timer), I really don't know how to modify the libraries to get it working.

There are two timers on the Arduino, and you may be able to make both works aside. DmxSimple explicitly says it uses the timer #2, whereas it is not clear for NewPing. But the NewPing library can work without using a timer. You can make the DmxSimple work using its timer (which is mandatory for close-to-real-time interaction with its bus), whereas you can handle the sonar ping in the loop function:
void loop() {
int dst = sonar.ping_cm();
delay(50);
DmxSimple.write(1, dst);
}
There you shouldn't have timers conflicting.
Looking at the source code of NewPing, it uses Timer2 if you use the timer_us()/timer_ms() functions, but no timer otherwise. But if you run it on an Arduino Leonardo (or Arduino Micro or any other ATmega32U4 based microcontroller), it will use Timer4 which is not conflicting with DmxSimple.
If you want to patch the NewPing library to use Timer3, you may want to replace this in NewPing.cpp:
OCR2A = 249;
TIMSK2 |= (1 << OCIE2A);
with
OCR3A = 640;
TIMSK3 |= (1 << OCIE3A);
and in stop_timer:
TIMSK2 &= ~(1 << OCIE2A);
with
TIMSK3 &= ~(1 << OCIE3A);

Related

atmega16 serial communication not working (both uart_send and uart_receive)

I'm trying to communicate between a BLE using Atmega16 with android app(Just to send a character and receive it back).
I'm able to transfer data between BLE with arduino and app but when i'm using atmega16 micro-controller it's not working. When i'm trying to send a character and recieve it back some characters are getting back exactly (0 to 9,q,w,r,t,y,u,p,z,s,x,v,:,^,=,?,;), but others are not.
I think the problem is with my baud rate and CPU frequency. I tried many combinations but none of them are returning whole charcters back exactly.
These are my uart initialization and Interrupt functions
I've used CPU frequency 14.7456MHz and Baud rate 230.5k. I tried using baud rate 9600 at 8Mhz frequency but for these values random garbage values are coming back.
#define F_CPU 14745600UL
#define BAUDRATE 230500UL
#define BAUD_PRESCALE ((F_CPU / (BAUDRATE * 16))) - 1
void uart_init() {
UBRRL = (unsigned char) (BAUD_PRESCALE);
UBRRH = (unsigned char) (BAUD_PRESCALE >> 8);
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
// Need to disable JTAG twice. Read spec sheet for details.
// http://www.avrfreaks.net/comment/618701#comment-618701
MCUCSR = (1 << JTD);
MCUCSR = (1 << JTD);
}
ISR(USART_RXC_vect) {
uint8_t c = UDR;
UDR = c;
PORTA = c;
}
Any help!!
We need to change fuse bits not only when using external crystal/resonator, but we also have to change fuse bits when we are using internal RC oscillator. The default configuration of fuse bits is for frequency 1Mhz. For different frequencies of internal RC oscillator we need to set the fuse bits accordingly. This fuse bit calculator will be helpful.
How to set fuse bits is explained in this blog.
I don't know earlier that we have to set different fuse bit configurations for different internal frequencies also.
Finally i solved my problem with your support. Next i have to transfer strings and much more.
Thank you all.
If you are writing it in Atmel studio. It has terminal window exstension (it worked on 6.0 version, on 7.0 I don't know now).
If you're not using Atmel studio, than open some terminal and listen what's coming. If you are getting dummy data, it means you haven't configured fuse bits properly as is answered upper.
If you're using Atmel studio, I suggest use some STK500 like programmer and integrate it in Atmel studio. Program devices from there. It's more comfortable and fuse bit settings is easy from there.
I see you're using 14745600 hz oscillator. You have to set fuse bits for External high frequency oscillator ready.
If you want to disable JTAG it's possible to disable it from fuse bits.

Using embOS functions within USB ISR for LPC1788

I'm developing software for an NXP LPC1788 microcontroller, and I'm using the embOS RTOS. Whenever a message is received over USB, I want to use the OS_PutMailCond() function to store the USB message in a mailbox which a handler function is waiting on. In other words, I want to make message handling interrupt-driven.
The embOS user manual can be found here. Page 145 describes the OS_PutMailCond() function.
Whenever a USB message is received, it triggers the USB interrupt service routine on the LPC, but to let embOS know that it's an ISR I have to place OS_EnterInterrupt() and OS_LeaveInterrupt() at the start and end of the ISR respectively. This is necessary if I want to call embOS functions within it, including OS_PutMailCond().
The problem is that if I put OS_EnterInterrupt()/OS_LeaveInterrupt() anywhere within the USB ISR, the USB stops functioning properly and Windows informs me that the device has malfunctioned.
I have no idea why this is the case. We've tried something similar for handling messages over CAN, as shown below, and it works fine.
void CAN_IRQHandler(void)
{
OS_EnterInterrupt();
...
if (MBfieldCANframeInitialised)
OS_PutMailCond (&MBfieldCANframe, &recMessage);
OS_LeaveInterrupt();
}
OS_EnterInterrupt() and OS_LeaveInterrupt() are described on pages 252 and 253 of the linked manual. From the additional information section of the former:
If OS_EnterInterrupt() is used, it should be the first function to be
called in the interrupt handler. It must be used with
OS_LeaveInterrupt() as the last function called. The use of this
function has the following effects, it:
disables task switches
keeps interrupts in internal routines disabled
EDIT
I've investigated further and found out that using OS_EnterInterrupt() and OS_LeaveInterrupt() within the USB ISR (and other ISR's like the one for the GPIO when a rising or falling edge is detected on a pin) causes an OS error. The error value is 166, which means "OS-function called from ISR with high priority".
I'll update if I find out anything else.
Problem solved. It turns out the guy that made this work for the CAN ISR changed the code of one of the embOS source files to set the CAN ISR priority level from 0 to 29 (higher level = lower priority). I did the same thing for the USB ISR:
void OS_InitHW(void) {
OS_IncDI();
//
// We assume, the PLL and core clock was already set by the SystemInit() function
// which was called from the startup code
// Therefore, we don't have to initailize any hardware here,
// we just ensure that the system clock variable is updated and then
// set the periodic system timer tick for embOS.
//
SystemCoreClockUpdate(); // Update the system clock variable (might not have been set before)
if (SysTick_Config (OS_PCLK_TIMER / OS_TICK_FREQ)) { // Setup SysTick Timer for 1 msec interrupts
while (1); // Handle Error
}
//
// Initialize NVIC vector base address. Might be necessary for RAM targets or application not running from 0
//
NVIC_VTOR = (OS_U32)&__Vectors;
//
// Set the interrupt priority for the system timer to 2nd lowest level to ensure the timer can preempt PendSV handler
//
NVIC_SetPriority(SysTick_IRQn, (1u << __NVIC_PRIO_BITS) - 2u);
NVIC_SetPriority(CANActivity_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
NVIC_SetPriority(CAN_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
NVIC_SetPriority(USB_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
OS_COM_INIT();
OS_DecRI();
}
I found this in the embOS documentation:
Why can a high priority ISR not use the OS API ?
embOS disables low priority interrupts when embOS data structures are modified. During this time high priority ISR are enabled. If they would call an embOS function, which also modifies embOS data, the embOS data structures would be corrupted.

Arduino Uno PWM pins conflict

I built this motor shield based on the L298N chip to control two motors of a tank. It uses pins 5 and 6 for one motor, and pins 10 and 11 for the other.
While trying to add a TSOP 4838 in order to control the tank with an IR remote I noticed that moving the motor on pins 10/11 in reverse only works at full speed - that is, a HIGH (255) value on pin 11. Anything below that value doesn't output anything on pin 11 (measured voltage on those pins is 0 V).
For the remote I use this library. The IR receiver is connected on pin 2 (but the pin doesn't matter). The problem is the library code itself. The line that enables IR listening irrecv.enableIRIn(); is what is causing the problem. I learned that there is a conflict of internal Arduino timers and the pins used for PWM by the shield.
This is the code to power the motor in reverse:
#include <IRremote.h>
// IR receiver configuration
const int irPin = 2;
IRrecv irrecv(irPin);
// Motors configuration
const int mLeftPin1 = 10;
const int mLeftPin2 = 11;
const int mRightPin1 = 5;
const int mRightPin2 = 6;
void setup()
{
// Start IR
irrecv.enableIRIn();
// Setup motors
pinMode(mLeftPin1, OUTPUT);
pinMode(mLeftPin2, OUTPUT);
pinMode(mRightPin1, OUTPUT);
pinMode(mRightPin2, OUTPUT);
// Move left motor in reverse, slower speed
analogWrite(mLeftPin2, 100); // This works only with 255 instead of 100
digitalWrite(mLeftPin1, LOW);
}
Now, I found here that the pins used by the timers on Arduino Uno are:
Pins 5 and 6: controlled by Timer0
Pins 9 and 10: controlled by Timer1
Pins 11 and 3: controlled by Timer2
So my questions are:
Why does the shield in the instructable use pins 10 and 11 for PWM ? They correspond to 2 different timers. Why not 9 and 10?
In order to use the IR along with the motor shield, what timer should I configure the IR library to use?
If the answer is 2, a line should be uncommented in IRremoteInt.h. I am guessing the Uno would take the else branch at line 68, although only timer1 and timer2 are there. I wonder why timer0 couldn't be used for the Uno.
Although I'd like to leave cutting traces and resoldering as a last option, another possibility would be to change the pins used by the shield, but which? And I am guessing this would also be paired with configuring the timers to PWM on other pins than default, but I don't know anything about timers/interrupts and my knowledge of Arduino and C is limited.
I made this a long question, because I want to learn not just solve the problem, so feel free to explain more than what is asked.
While looking up for a solution I also found other conflicts to keep in mind when using PWM or timers:
Timer0 is an 8-bit timer, it can hold a maximum value of 255. It is used by delay() and millis(), so there are consequences when messing with it
Timer1 is a 16-bit timer, it can hold a maximum of 65535 (an unsigned 16-bit integer). The Arduino Servo library uses this timer
Timer2 is an 8-bit timer used by the Arduino tone() function
And, of course, the IRremote library uses TIMER_RESET, so depending on which timer it uses it can conflict with the associated pins.
Not all hardware is designed in the best way. Using 10 and 11 is indeed wasteful because it requires two timers.
2/3. Ideally you will use a timer that is not Timer0. Here's some more details on timers/interrupts:
The Arduino chip (328P) has three timers. Each timer can be used for multiple uses, however it is important to note that you can only have one timer interrupt enabled for each timer.
Take Timer0 for example. It interrupts in order to generate the proper delays for the delay() and delay_us() methods. It also is used for the PWM outputs on pins 5 and 6. This can happen because the PWM outputs don't use a timer interrupt, they use separate output compare modules.
Now looking specifically at your problem, it should work fine, even though you have a PWM output using timer2, the PWM does not take an interrupt on timer2 so the IR library should be free to use that interrupt. However, looking into the IR library code, we see this piece of code:
ISR(TIMER_INTR_NAME)
{
TIMER_RESET;
It appears that every time it interrupts, it resets the timer count. This could be why your PWM output is not working properly. The output compare module is waiting for a certain tick count, and it never reaches that.
As to why it somehow works at 255, we can take a look at the analogWrite code:
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
So by writing 255, the analogWrite code ignores the whole PWM and output compare thing, and just writes the pin high.
Finally, as to solving your problem, I would personally go the route of not using pins 11 and 3 (timer2). Yes it will require a small rewiring, but that way you can free up timer2 for the IR library to use.
Alternatively, you could poke around the IR library and try to make it work without resetting the count.
Pay attention to the board used, if you use Arduino Uno, then the code responsible would be: // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
else
//define IR_USE_TIMER1 // tx = pin 9
define IR_USE_TIMER2 // tx = pin 3
endif
I had the same problem with a prebuilt L298 V2 motor shield.
The pins were marked like this on the shield:
Motor1: pin 3 and 5
Motor2: pin 6 and 9
I use PIN10 instead of 3 and using a small workaround: I put a wire from PIN10 to PIN3 on the SHIELD.
My project was to control my robot with a SAMSUNG TV remote control.

beginning with winAVR

I have 20 odd years in programming starting from pascal 7 to delphi. I want to start programming micro controllers using C and the tool most electronics kit recommend is winAVR with programmers notebook. I have installed the software and would like to start compiling code and I'm lost to say the least and can't find any simple documentation to get myself onto a track where I can start testing code. Can anyone offer some good starter material?
Whereas for PC's the usual first program is "Hello, World!", in the embedded world (one lacking displays, as least to start with, the equivalent is the blinky led: you attach a LED to some output pin of your processor (don't forget the current-limiting resistor!: you need a resistor in series with the LED), and you make the LED blink. You can find plenty of blinky LEDs for AVR, but we can write one right here:
// The next define tells delay.h what your CPU speed is, assuming 1Mhz
#define F_CPU 1000000UL
#include <util/delay.h>
main() {
while(1) { // loop forever
DDRB = 0xFF; // Set the direction of all pins
// on port B to OUTPUT (can change to some other port)
PORTb = 0xFF; // Set all pins on port B high (can change to some other port)
_delay_ms(1000); // Wait one second;
PORTb = 0x00; // Set all pins on port B low (can change to some other port)
_delay_ms(1000); // Wait one second;
}
}
It should compile on WinAVR, and load correctly. Change PORTB and DDRB to some other port of you'd like. Note that this program changes all the pins on that port: so if your port B has 8 pins, all of them will blink a led hooked up to them. Don't forget the current-limiting resistors, and that LEDs are directional: they only work when plugged in one way, and not the other.

Steps to make a LED on or off from a C program using Serial Port?

I knew there is a similar post:
Steps to make a LED blink from a C/C++ program?
But now I am working on a arm-based development board, and it seems to have two serial ports that I could use it to make a LED on or off.
Basically I think the flow is , make one pin in serial "1" or on and the LED will be turned on and "0" to make it off.
Is there some reference code in C-language I could refers?
Generally speaking, the board should come with some Board Support Package (BSP) which lets you control the built in I/O. Look for a serial library if you really want to use the Hardware flow control signals.
I'd recommend looking for some GPIO (General Purpose I/O, or digial I/O) on the board, which typically lets you configure it as an input or an output. You should be able to connect the LED via a current limiting resister between a digital I/O line and a ground pin. Make sure you have the LED oriented correctly if you connect it backwards it will block the current instead lighting. And as always make sure you check it out with a digital voltage meter before connecting it.
Even if you don't have a BSP for digital I/O the configuration is usually pretty simple.
Set a bit in a register to enable it, set bit in another register to select input or output they will normally be arranged in 8-bit "ports." Some systems allow you configure individual I/O pins, other will only allow you to configure the whole port for input or output. Then you just write a 1 or 0 to the bit you want to control in an write/output register.
ARM chips typically have a considerable amount of built in peripherals today, so most boards will just be bringing the I/O out to physical connectors on the board and you may need to read the chip vender's documentation to find the register memory map. Better board venders will supply documentation, a library (BSP) and examples. Luminary Micro even supplies chips with built in ethernet MACs and PHYs, just add a connector and Magnetics and you have a 1 chip Webserver.
This will, I'm afraid, be heavily dependent on the specifications of the particular arm-based development board you are using.
You need to find documentation specific to that board.
I used to do this kind of programming before.
You need to study the serial port connection
http://www.lammertbies.nl/comm/cable/RS-232.html
http://www.beyondlogic.org/serial/serial.htm
It has +5v, -5v on the output, I can't remember clearly now. Not every pin is needed.
I never use ARM before, but I use a 8-bit PIC controller to program it. I guess you can find a lot of example online.
The preferred alternative for controlling a GPIO is via a BSP. Because this BSP (board support package) does all the work for you in setting all peripherals to good defaults and and allowing you to call a function. Possibly your BSP of choice will have a function to write a byte to an 8-bit GPIO port; your LED will only have one bit. In this case your C code could look like: (at least: it will work like this on Luminary Micro kits). (Example code; requires a bit of extra work to make it compile especially on your kit).
/* each LED is addressed by an address (byte) and a bit-within-this-byte */
struct {
address, // address of IO register for LED port
bit // bit of LED
} LEDConfigPair;
struct LEDConfigPair LEDConfig[NUMBER_OF_LEDS] = {
{GPIO_PORTB_BASE,0}, // LED_0 is at port B0
{GPIO_PORTB_BASE,1} // LED_1 is at port B1
} ;
/* function LED_init configures the GPIOs where LEDs are connected as output */
led_init(void)
{
U32 i;
for(i=0;i<NUMBER_OF_LEDS;i++)
{
GPIODirModeSet( LEDConfig[i][0], LEDConfig[i][1], GPIO_DIR_MODE_OUT );
}
}
/* my LED function
set_led_state makes use of the BSP of Luminary Micro to access a GPIO function
Implementation: this BSP requires setting 8 port wide IO, so the function will calculate a mask (
*/
set_led_state(U8 led,bool state)
{
U8 andmask;
U8 setmask;
andmask = ~(1 << LEDConfig[led].bit);// a bitmask with all 1's except bit of LED
if (true == state)
{
setmask = (1 << LEDConfig[led].bit); // set bit for LED
} else
{
setmask = 0;
}
GPIOPinWrite(LEDConfig[led].address, andmask, setmask);
}
Of course this is all spelled out; it can be done in a single lines like this:
#DEFINE SETLEDSTATE(led,state) GPIOPinWrite(LEDConfig[led].address, ~(1<<LEDConfig[led].bit),(state<<LEDConfig[led].bit))
this will do the same, but only makes sense when you can dream bit masks, and you only want to toggle some LEDs to debug the real program...
The alternative: bare metal.
In this case you need to set up everything for yourself. For an embedded system, you need to be aware of pin multiplexing and power management (assuming memory controller and cpu clocks are already set up!)
initialization: set pin multiplexing in such a way that the function you want to control is actually mapped on the package.
initialization of pheripheral (in this case either a UART, or a GPIO function on the same pin)
You can't do it using Rx or Tx pins of Serial port. For that you just need to control the RTS or CTS pins of serial port.
Just google for "access COM port in VC++ code" and then control the RTS and CTS status pins to turn ON and OFF any external device.

Resources