Show Posts
Pages: 1 2 [3] 4 5 ... 22
31  Using Arduino / Programming Questions / Re: Adding Delay to Optiboot for RS-485 support on: August 19, 2012, 02:09:52 pm
Sorry, just saw this...

Yes, I didn't change anything in the original README.txt, IIRC. 

I should really clean up the bootloader part of the source tree - I don't like it being so out of sync with the core optiboot, but at the same time, I expected it to be extremely rare that anyone actually tried to build and upload the booloader. (We pre-program them with the bootloader.)

Yes, you use make nanoMoCo, or make nanoMoCo_isp

I do realize there are probably easier ways than having to power cycle the board to update the firmware, but we were shooting for a form factor first and foremost, so things like dual interfaces for programming/etc. kinda fell by the wayside.

!c
32  Using Arduino / Programming Questions / Re: Moving two servos incrementally every second on: July 08, 2012, 10:31:19 am
Break it down into several, smaller problems -- you need to:

1) Measure the passing of time (so you can do something once every second)
2) Change a value
3) Write the changed value

So, consider the following pseudo-code and go from there..

Code:
if currentTime - lastTime greater than threshold
   then
       increment value
       write to motor
       set lastTime to now

To change the value in a variable, just set its new value - you can even use its old value to set it, e.g.:

Code:
  var1 = var1 + 10;

The scope of the variable determines its life...  If you declare it global (outside of a function), any changes you make are global, you can access it again from anywhere else, e.g.:

Code:

int foo = 1;

void setup() {
}

void loop() {

  foo = foo + 1;
}

!c
33  Using Arduino / Project Guidance / Re: How to stop execution of a sketch? on: January 11, 2012, 11:34:25 am
It's worth noting, as mentioned by a few above, what does "stop" mean?

Does it mean - stop taking some prescribed action and wait until some signal occurs to resume activity, or does it mean that the sketch should perform a single activity, and then do nothing else until it has been power-cycled or reset, or, even more - does it mean the device should stop running entirely after performing some action?

For 3rd, you will need to control the state of the chip's sleep mode, as people have mentioned.

For the 2nd, as noted - simply put all of the logic in setup() and have a blank loop.

For the 1st, consider using a simple state machine:

Code:

void loop() {

  if( something == true ) {
     performAction();
  }
}

Of course, your state machine will be arbitrarily complex based on your actual needs - but it is important to differentiate between the three possible outcomes as the solution to each is different.

!c
34  Using Arduino / Motors, Mechanics, and Power / Re: Steppermotor library or arduino limitations? on: January 10, 2012, 09:40:10 am
I have had no issue -sending step signals- at 5,000 steps/second with easing (quadratic or linear), and 10,000 steps/second without easing.  Of course, I have no motors on-hand that can come close to that speed at the 12V I tend to work with.  The primary difference was that instead of using digitalWrite(), I fixed my pins in hardware and used the pin register directly, and used timerone to drive the stepping asynchronously so that I could do other things.  The motion is a little different in that the minimum off-period between steps is fixed (i.e. one cycle of the timer), but to get asynchronous stepping (so I can do other stuff), was more valuable than trying to achieve off periods smaller than the interrupt period.

Of course, it only supports a single motor, so you'd slow down a bit supporting more motors, but for an example of how to do it up to 10,000 steps/second see: http://openmoco.org/docs/OMLibraries/class_o_m_motor.html  The source code can be downloaded from http://openmoco.svn.sourceforge.net/viewvc/openmoco/OpenMocoComponents/nanoMoCo/trunk/Libraries/OMMotor/

It is possible to get quite fast code if you profile your solution and test where the slow parts are.  

If you're not able to go faster than 1,000 steps/second, it's likely not a code problem and you should be running a proper chopping driver with the correct voltage and current for your application.

!c
35  Using Arduino / Installation & Troubleshooting / Re: Arduino Uno Rev3 vs. Rev2 reset circuit changes on: January 09, 2012, 06:12:02 pm
Lefty,

Thank you very much for the explanation.  Now that you mention it, I do recall having seen that thread a while back...

Sounds like a pretty straight-forward work-around, I'll test it and inform my users.  I expect the issue being our shield has set the conditions just right for the R2 boards.  I don't know that it's all R2 boards, but all people reporting the issue on my end have been R2 users.  But, as they say - you don't hear about it when things work right. =)

!c
36  Using Arduino / Installation & Troubleshooting / Arduino Uno Rev3 vs. Rev2 reset circuit changes on: January 09, 2012, 05:14:08 pm
Hello all,

Does anyone know what the exact changes were to the "reset circuit" between Rev 2 and Rev 3 of the Arduino Uno?  The changelog only says "Stronger RESET circuit."

I ask because I have a number of customers who have the Rev2 Uno which does not work with my shield*, while the Rev1 and Rev3 do, and I'm trying to find a workaround for them.

* - the problem is that the sketch does not start without first pressing the reset button.  This only happens with Rev2 Uno's.

Thanks!

!c
37  Using Arduino / Microcontrollers / Re: Modifying Optiboot to Upload Sketches over RS485 on: November 10, 2011, 12:09:20 pm
You are deciding to switch over from transmit to receive when the transmit buffer register is empty. However, this becomes empty when the last byte of data is transferred from it into the output shift register. Therefore it is still being clocked out of the shift register when you switch over. As a result you chop off the last byte and it doesn't get completely sent. This is a problem with RS485 communications.

Spot-on Mike, Spot-on.  I had added delays before, but they always seemed to go into the next received byte, blocking me from receiving it.  You reminded me to remember that there's about 70nS signal delay on the transceiver (35nS to go from low to high, and another 35nS to go from high to low), and I just had an eye-rolling moment where I realized that by the time TXC0 went to one, I didn't have to wait for -all- bits to go out, only the last, and doing some math to find the best bitrate (i.e. that which adding 70nS got me closest back to a full uS), led me back to 115200 (woot.) with the following code:

Code:
  while (!(UCSR0A & _BV(UDRE0)));

  PORTD |= _BV(PORTD5);
 
  UCSR0A |= _BV(TXC0);
 
  UDR0 = ch;
 

  while(!(UCSR0A & _BV(TXC0)) );

    // delay for period to send one bit (8.68uS) plus rise and fall delay time on transceiver (70nS)
  _delay_us(8.75);
 
  PORTD &= ~_BV(PORTD5);

.. and now it works, every single time - like a charm. =)


Quote
On a wider issue how are you going to implement the auto reset that normally occurs on opening the serial port on the PC.

I changed the quickboot sequence to also look for a new sketch after power on, and increased watchdog timer to 8s to give a little extra time.  There is no auto-reset, b/c I'm only using two wires for the RS-485, and even though the cable I have has RTS line, I choose not to use it. (Because there is no where to apply it without affecting normal cabling options between devices, and still use the same cable for programming or normal operations.)

e.g.:

Code:
  // Adaboot no-wait mod
  ch = MCUSR;
  MCUSR = 0;
 
  // add check for power-on reset
  if (!(ch & _BV(EXTRF)) && !(ch & _BV(PORF)) ) appStart();

Thanks for the help!  It's always nice to go have great minds to lean on, went from what seemed like an intractable problem (I had never touched the bootloader before, always just used standard one or just burned hex w/o one using ISP), to a working model in just north of 24 hours - would've been a lot less had I paid better attention to my arithmetic early on in the process *grin*  Not to mention, I just got the secret juice to bump my normal RS-485 traffic up to 115.2k from 9.6k: would've never known about _delay_us if I hadn't touched the bootloader - fractional uS delays are nice! Admittedly, there's probably some inaccuracy here, but it works well enough.

Thanks again!
38  Using Arduino / Microcontrollers / Modifying Optiboot to Upload Sketches over RS485 on: November 10, 2011, 09:20:01 am
A board I'm currently working on has a primary interface over RS485 (it is expected to be part of a multi-drop network, with several like and different devices at the same time - with a single master controlling them).  All of the communication works great, and the network design hasn't shown any issues yet, etc. The RS485 driver is an SN75176AD and its output goes to the RX/TX lines on the Atmega328P, which is running at 16Mhz w/ a crystal and 5V. 

The board is designed to fit in as small of a space as possible (it's 1.5"x1.5") - it could be smaller, yes, but it has an A4983, Dual OK, and of course the SN75176 plus all the accoutrements, with pin-pads and such that's about as small as I've gotten it at this stage.  Given this, I decided that adding a USB->serial converter was a luxury, but left the standard RX/TX lines accessible via pins.

The challenge I'm facing: RS-485 is the primary interface for the vast majority of users in its final destination.  As such, for PC communication, a special USB->RS-485 adapter is required.  I don't want the users to have one interface for interaction and yet another for programming the board, both because buying two USB adapter cables is an undesired expense on the user, and adding a USB port on the board will prevent it from being used in some of the cases which it is designed for (where the 1.5"x1.5" footprint is the absolute maximum that will fit).

After modifying optiboot 4.4 to check for uploads on power-up, and not just after external reset, I also changed it to eliminate interference from the RS485 driver on the RX line during upload using the standard RX/TX lines, by adding the following to the main function:

Code:
  DDRD |= _BV(PORTD5);
  PORTD |= _BV(PORTD5);

Digital 5 (PORTD5) is the control line which is shared between the DE/RE pins on the driver.  Putting the driver in transmit mode (DE = RE = HIGH) causes it to release the RX line, which allows upload using the standard RX/TX lines (and another arduino salvaged for its FTDI interface =).  So, at least this option works, ok.

Now, I'm working on the ability to upload via the RS485 interface, which requires the board to put the transceiver (ok, I've been calling it a driver, because it's a shorter word =) into the transmit state before transmitting data, and then putting it back into receive state to get more data.  This is where I've run into a stumbling block, and I'm wondering if anyone else has tried something like this and can see what I've been missing as obvious - I hope!

So, to control the state of the driver, I made sure to change the above mod to the put the driver into receive mode first, and then modified putch() in the following way:

Code:
void putch(char ch) {
#ifndef SOFT_UART

  while (!(UCSR0A & _BV(UDRE0)));

    // enable transmit mode
  PORTD |= _BV(PORTD5);
    // clear out TXC0
  UCSR0A |= _BV(TXC0);
 
  UDR0 = ch;
 
    // wait for transmit complete
  while(!(UCSR0A & _BV(TXC0)) );
    // enable receive mode
  PORTD &= ~_BV(PORTD5);

I can validate that it somewhat works, as I see the first response byte go back to the RS485 cable (clear housing = I can see RX/TX leds on the adapter, RX = green TX = red) every time, but then it tends to get stuck here and we get the inevitable timeouts from avrdude. 

An odd thing I encountered during testing was that if I disabled (via defines in the makefile) the LED flash functions, and then added a  LED_PIN |= _BV(LED) to the beginning of the putch() function with no corresponding change to turn off the LED, it would light up for a fraction of second, no matter what the first watchdog timer is set to (went to _8S).  Which, seems to indicate that it's bailing out quickly on a timeout?  If I removed the first call to config the watchdog entirely, surprisingly about 5% of the time, I can get it to start uploading the sketch, only to lose sync at some random point.  This, of course, only happens at 57,600 - any lower or higher baud rate, and it never starts uploading.  Natch: to go to the lower bauds, like 9600, I had to add a special define to avoid the SOFT_UART, because the code included there triggers compiler errors.

Does anyone have any experience with this, that they could shed some light on why the oddity?  Why would the first byte response be ignored?  Or, is it possible that the driver is not ready when the first response from avrdude comes after the first byte sent by the bootloader?

Thanks!
39  Using Arduino / Microcontrollers / Re: Problems with Optiboot vs. Standard Arduino Bootloader on Custom Board on: November 10, 2011, 08:50:44 am
I'd encourage you to get the newer optiboot source from the 1.0 release candidate distributions...

When you say it only flashes after the initial ISP, are you saying you also see no flashes with a manual reset, or hard poweron?


I'll check out the 1.0 version, thanks - although I think I do currently have the latest, unless the Arduino 1.0 branch is a different version than 4.4.

Yeah, the problem was that optiboot (at least the version I have here), as noted above only waited for a firmware upload when an external reset was triggered, adding the check against PORF resolved that, allowing me to upload after a power-on (since the boards do not have a reset switch, although fashioning one is possible using the ISP pins, IIRC).

I can upload using the standard UART lines now after a power-on, which is a good start on my quest.  I'll post another topic on the current troubles I'm having, which have little to do with optiboot, and more to do with my changes =)

40  Using Arduino / Microcontrollers / Re: Problems with Optiboot vs. Standard Arduino Bootloader on Custom Board on: November 09, 2011, 12:13:32 pm
Code:
 // Adaboot no-wait mod
  ch = MCUSR;
  MCUSR = 0;
  if (!(ch & _BV(EXTRF))) appStart();

It only checks for an 'external reset', which is not the same as 'power on reset', 'brown out reset' or 'watchdog reset'.


That's an excellent pointer - it worked like a charm changing it to this:

Code:
if (!(ch & _BV(EXTRF)) && !(ch & _BV(PORF)) ) appStart();

Now, I can upload sketches and they run fine!

Thanks again!

41  Using Arduino / Microcontrollers / Re: Problems with Optiboot vs. Standard Arduino Bootloader on Custom Board on: November 09, 2011, 11:11:30 am
Unfortunately, auto-reset won't work b/c I won't be using anything with an RTS signal.  (It will be running on an RS-485 bus and adding a USB interface, while possible, is not preferred due to added cost and size constraints.)

As for adjusting the timeout - I presume it is the watchdog timer that handles this? i.e., would changing this in main() do what I think it will?

From:
Code:
  // Set up watchdog to trigger after 500ms
  watchdogConfig(WATCHDOG_1S);

  /* Set LED pin as output */
  LED_DDR |= _BV(LED);

To:

Code:
  // Set up watchdog to trigger after 500ms
  watchdogConfig(WATCHDOG_2S);

  /* Set LED pin as output */
  LED_DDR |= _BV(LED);

Unfortunately, anything longer seems to only be supported by atmega8.

However, even without the longer timer - shouldn't the start led flash sequence happen at every power-on?  As I stated before, it only happens immediately after programming w/ ISP, and never flashes again under any circumstances.

Thanks!
42  Using Arduino / Microcontrollers / Problems with Optiboot vs. Standard Arduino Bootloader on Custom Board on: November 09, 2011, 10:03:39 am
Hi guys,

I'm hoping one of you might be able to help determine where the problem I'm encountering is coming from.

I'm having an issue attempting to use the optiboot bootloader on a custom board, where the standard arduino bootloader (from bootloaders/atmega/ATmegaBOOT_168_atmega328.hex) works fine. 

First, a quick description of the board: it's using an Atmega328P-AU chip, with 16Mhz crystal, running at 5V.

I am attempting to upload the bootloader using ISP via an Olimex AVR-ISP500.

Burning the standard arduino bootloader works as expected, and the bootloader behaves as expected - I am able to upload sketches over serial.  However, attempting to burn the optiboot_atmega328.hex to the board results in the start flash sequence only happening once - immediately after ISP programming completes.  This sequence is never displayed again, and the bootloader does not respond to upload data over serial.

I have tried all of the following ways of uploading the optiboot bootloader:
 - make atmega328_isp in the optiboot directory
 - select board type as 'Uno' and burn via the Arduino IDE
 - running avrdude manually

The fuses seem to all be set correct: efuse = 0x05, hfuse = 0xDE, lfuse = 0xFF

A note as to how I am uploading sketches via serial: the board does not have an FTDI chip, so I am using a Diecimila with no chip installed, sharing ground and TX/RX with my board - power cycling my board at the right moment so that it starts just a moment before the upload starts.  This, again, works perfectly with the standard arduino bootloader.

Any advice on where I'm going wrong, or how to correct the issue?  I'd like to use optiboot, as I need to test a few changes to the bootloader for my needs, and the standard arduino bootloader is of unknown source, given that the supplied arduino bootloader source does -not compile- without modifications.

Thanks!
43  Using Arduino / Programming Questions / Re: Adding Delay to Optiboot for RS-485 support on: November 08, 2011, 11:30:11 am
d'oh - I should do more testing before posting, it seems.  =)  My problem is not here, but somewhere else.  Setting LED_START_FLASHES=3 and LED_DATA_FLASH results in pin13 not flashing, so I think there's a bigger problem somewhere else. I'll post back if I find anything.

!c
44  Using Arduino / Programming Questions / Adding Delay to Optiboot for RS-485 support on: November 08, 2011, 10:32:05 am
Hi everyone, I'm hoping you can help me with this little problem...

I've patched optiboot.c to control the DE line for an RS-485 driver when sending data, in hopes that I could get to programming my device over RS-485 (it's a custom board, and I'd prefer to not have to fiddle around and switch all sorts of stuff to program vs. interact with it - the RS-485 driver's output are properly hooked up to standard TX/RX, and communication works fine over RS-485, and TTL serial works fine when I disable the driver via a hardware jumper).

In a quest to perform this activity, I've added the following to optiboot.c's putch() function:

Code:
void putch(char ch) {
#ifndef SOFT_UART

  PORTD |= _BV(PORTD5);
  PORTB |= _BV(PORTB5);
 
  while (!(UCSR0A & _BV(UDRE0)));
  UDR0 = ch;
 
   PORTD &= ~_BV(PORTD5);
   PORTB &= ~_BV(PORTB5);

Digital 5 is the DE pin, and digital 13 is just there for debug purposes.  I've also included the requisite DDR.. instructions up in main():

Code:
  DDRD |= _BV(PORTD5);
  DDRB |= _BV(PORTB5);

... and clocked it back to 9600 for uploading*, as speed isn't as important as simply being able to use the RS-485 interface, added a boards definition, and so forth.

* - this required adding a define to get around the SOFT_UART automatic definition, which triggered all sorts of errors compiling.

All this is fine and dandy, got it up to the board, etc. and then got the inevitable timeouts during sketch upload (replicating process that would've happened using the TTL interface successfully when defined as a duemilanove w/ atmega328p.).

As a consequence, I didn't see my pin13 light up during the process - and I know I've had issues with time to clear out bits from the RS-485 driver when switching the DE pin state, so I thought I'd add a delay, which is where I hit the real roadblock:

Code:
#include <util/delay.h>

...


void putch(char ch) {
#ifndef SOFT_UART

  PORTD |= _BV(PORTD5);
  PORTB |= _BV(PORTB5);
 
  _delay_ms(1);

This triggers an error during hex upload:

Code:
avrdude: input file optiboot_nanoMoCo.hex auto detected as Intel Hex
avrdude: ERROR: address 0x8008 out of range at line 33 of optiboot_nanoMoCo.hex
avrdude: write to file 'optiboot_nanoMoCo.hex' failed

Any thoughts on the best way to add a delay here for testing purposes?  Or, perhaps, any recommendations towards the overall goal? (Programming over RS-485 interface.)

Thanks!

!c
45  Topics / Robotics / Re: Big Stepper on Arduino on: September 22, 2011, 12:48:28 pm
Welcome to the world of motion control.  You've got big steppers, but now what?  Why did you need such powerful steppers?  You say "I need speed and torque," that's a meaningless statement, every motor delivers "speed" and "torque".  How much speed do you need?  How much torque? What's your drivetrain?  What's your payload?  How fast must it move from one location to another?  How distant is one location from another and what's your desired positioning resolution?  All of these things are as important as the selection of the motor and the driver.

If you chucked down a few dollars, you can get a proper high-performance step/dir driver like those from Gecko: the G210 can do 7A @ 80V.  http://www.geckodrive.com/g210-p-35.html 

!c
Pages: 1 2 [3] 4 5 ... 22