Show Posts
Pages: 1 2 3 [4] 5 6 ... 415
46  Using Arduino / Motors, Mechanics, and Power / Re: Help with 19 servos and Mega on: August 04, 2011, 07:33:31 am
Quote
Usually a servo library is used that provides for the PPM control signals that standard hobby servos use.

I agree, i understand PWM and servo’s. But I was wondering why vinceherman doesn’t use the PWM but the digital out for driving his servos.

Quote
You don't use PWM output.  That is for driving DC motors and LEDs.
Just grab the digital pins and attach the servos.

It would be nice to see some more code to achieve that.

Chris

The Arduino servo library uses hardware timers to control servo pulses to enable many more servos to be controlled than if the hardware PWM capability was used. The source code for the Servo library is in the Libraries > Servo directory of the arduino distribution.
47  Using Arduino / Motors, Mechanics, and Power / Re: VarSpeedServo - a modified Servo library with speed control on: August 04, 2011, 07:28:53 am
Hi Mem,

it's nice to know, that you like it. Whether to add it to the main Servo-library should be considered carefully. From my point of view, you're welcome to add the code or any modification from it. However, please consider a few things first:
  • The speed control adds more memory to the servo structure. It's just a few bytes, but in large setup with many servos, you should check if this causes problems
  • The speed parameter doesn't relate to any real time measure. It's just a number and you can set some speeds but others not. For many applications, like moving something at a pleasant speed to look at, this is good enough. If some specific speeds are necessary, the model I used might not offer enough granularity.
  • I didn't really check if the interaction of the position update and attach/detach works in a reasonable manner. What happens if one detaches the servo while on a slow move and then reattaches it?
  • The method-name slowMove is clumsy and not really in line with the rest of the rest of the methods
  • Some proper documentation and samples are also necessary.

In short, it was mostly a quick hack to get landing gears on model aircraft extend and retract at a more more realistic pace. Going by the general feedback, it seems to be of use for some applications. If you think part of my work is useful to be added to the main library, feel free to go ahead.

Korman

Hi Korman,

I agree with all your points. But this thread and the other one I linked below got me thinking about possibly adding a sweep function with user setable speed that I may be able to do using just one more byte of RAM per servo. I would be interested to hear if this is something that would be generally useful and will start a new thread to discuss this if enough people are interested.
48  Using Arduino / Programming Questions / Re: Stalker V2 Help!! Set the time? RFID Logger on: August 03, 2011, 11:41:45 pm
The Stalker 2 RTC is not compatible with the DS1307 so the RTC1307 code in the Time download wont work.

Here is an updated version that autodetects the RTC type.
Save the files as RTC.cpp and RTC.h. Its used in the sketch like the old library but the name is now RTC

Code:
/*
 * RTC.cpp - library for DS1307 and RX8025 RTC chips
 
  Copyright (c) Michael Margolis 2009, 2010
  This library is intended to be used with Arduino Time.h library functions

  The library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
   30 Dec 2009 - Initial release for DS1307
   20 Nov 2010 - renamed to RTC and Added support for DX8025
 */

#include <WProgram.h>
#include <Wire.h>
#include "RTC.h"

//#include <HardwareSerial.h>  //only needed for diagnostics

const uint8_t DS1307_ADDRESS = 0x68; 
const uint8_t RX8025_ADDRESS = 0x32;

const uint8_t RX8025_CTL1   = 0xE0;
const uint8_t RX8025_CTL2   = 0xf0;

const uint8_t RX8025_24HR_MODE    = 0x20;      // set bit 5 for 24 hr mode

const uint8_t RX8025_NO_INTR      = 0x0;       // interupts off, INTA hi-Z
const uint8_t RX8025_INTR_PER_SEC = 0x4;       // INTA occurs once per second
const uint8_t RX8025_INTR_PER_MIN = 0x5;       // INTA occurs once per minute
const uint8_t RX8025_INTR_PER_HR  = 0x6;       // INTA occurs once per hour
const uint8_t RX8025_INTR_PER_MON = 0x7;       // INTA occurs once per month

// PUBLIC FUNCTIONS   

time_t RTCget()  // static function that can be used as a callback
{
  RTC.get();
}

rtcClass::rtcClass()
{

}
 
// returns true if selection is valid or autodetect succeeds in finding a device
bool rtcClass::begin(RTCDevice_t selection)
{
   device =  rtcUnknown; // default to indicate that no device is selected
   Wire.begin();
   if( selection == rtcUnknown)
   {
      // discover RTC device
      if(isAddressValid( RX8025_ADDRESS))
        selection = rtcRX8025;   
      else if(isAddressValid( DS1307_ADDRESS))
        selection = rtcDS1307;             
   }
   
   if(selection == rtcDS1307)
   {
       address = DS1307_ADDRESS;
       device = rtcDS1307;
   }
   else if(selection == rtcRX8025)
   {
     address = RX8025_ADDRESS;       
     device = rtcRX8025;
     writeRegister(RX8025_CTL1,RX8025_24HR_MODE); // RX8025 defaults to 12 hr mode so change to 24hrs   
     writeRegister(RX8025_CTL2,0);                // reset power on reset flag in control register 2     
   }
   //Serial.print("device = "); Serial.println(device, DEC);
   //Serial.print("address = 0x"); Serial.println(address, HEX);
   return (device != rtcUnknown); // returns true if a valid device selected
   
}   

time_t rtcClass::get()   // Aquire data from RTC and convert to time_t
{
  tmElements_t tm;
  read(tm);
  return(makeTime(tm));
}

void  rtcClass::set(time_t t)  // set RTC to given time
{
  tmElements_t tm;
  breakTime(t, tm);
  tm.Second |= 0x80;  // stop the clock
  write(tm);
  tm.Second &= 0x7f;  // start the clock
  write(tm);
}

// Aquire data from the RTC chip in BCD format
void rtcClass::read( tmElements_t &tm)
{
  Wire.beginTransmission(address);
  Wire.send(0x00);
  Wire.endTransmission();

  // request the data fields   (secs, min, hr, dow, date, mth, yr)
  if( device == rtcRX8025)
  {
     Wire.requestFrom((int)address, 8);
     Wire.receive();  // RX8025 gets an extra byte that is ignored
  }
  else     
    Wire.requestFrom((int)address, tmNbrFields);
 
  tm.Second = bcd2dec(Wire.receive() & 0x7f);   
  tm.Minute = bcd2dec(Wire.receive() & 0x7f);  // mask added for RX8025
  tm.Hour   = bcd2dec(Wire.receive() & 0x3f);  // mask assumes 24hr clock
  tm.Wday   = bcd2dec(Wire.receive() & 0x07);  // mask added for RX8025
  tm.Day    = bcd2dec(Wire.receive() & 0x3f);  // mask added for RX8025
  tm.Month  = bcd2dec(Wire.receive() & 0x1f);  // mask added for RX8025
  tm.Year = y2kYearToTm((bcd2dec(Wire.receive())));
}

void rtcClass::write(tmElements_t &tm)
{
  Wire.beginTransmission((int)address);
  Wire.send(0x00); // reset register pointer
 
  Wire.send(dec2bcd(tm.Second)) ;   
  Wire.send(dec2bcd(tm.Minute));
  Wire.send(dec2bcd(tm.Hour));      // sets 24 hour format
  Wire.send(dec2bcd(tm.Wday));   
  Wire.send(dec2bcd(tm.Day));
  Wire.send(dec2bcd(tm.Month));
  Wire.send(dec2bcd(tmYearToY2k(tm.Year)));   

  Wire.endTransmission(); 
}

// this method sets the RX8025 periodic interrupt to the given period
// the INTA pin is set low at the selected interval if the interrupt is enabled
void rtcClass::setPeriodicInterrupt( RTCIntrInterval_t interval)
{
  if( device != rtcRX8025)
     return; // only allow this method if using RX8025
  switch(interval) {
     case rtcIntrDisable    : writeRegister(RX8025_CTL1, RX8025_24HR_MODE | RX8025_NO_INTR); break;
     case rtcIntrEachSecond : writeRegister(RX8025_CTL1, RX8025_24HR_MODE | RX8025_INTR_PER_SEC ); break;
     case rtcIntrEachMinute : writeRegister(RX8025_CTL1, RX8025_24HR_MODE | RX8025_INTR_PER_MIN ); break;
     case rtcIntrEachHour   : writeRegister(RX8025_CTL1, RX8025_24HR_MODE | RX8025_INTR_PER_HR ); break;
     case rtcIntrEachMonth  : writeRegister(RX8025_CTL1, RX8025_24HR_MODE | RX8025_INTR_PER_MON ); break;
   }
}

// this method sets the INTA pin high impedence ready for next interrupt
// call this after every interrupt
void rtcClass::resetPeriodicInterrupt( )
{
  if( device == rtcRX8025)
     writeRegister(RX8025_CTL2, 0); // clear the control2 register
}

// PRIVATE FUNCTIONS

/// returns true if there is an i2c device at the given address
bool rtcClass::isAddressValid(uint8_t address)
{
   Wire.beginTransmission(address);
   Wire.send(0x00);
   Wire.endTransmission();
   Wire.requestFrom((int)address,1);
   delay(10);
   if (Wire.available() > 0 )
   {
      Wire.receive();
      //Serial.print("check for addr "); Serial.print(address,HEX), Serial.println(" returned true");
      return true;
   }
   //Serial.print("check for addr "); Serial.print(address,HEX), Serial.println(" returned false");   
   return false;       
}       

// sets the given register to the given value
void rtcClass::writeRegister( uint8_t reg, uint8_t value)
{
  Wire.beginTransmission((int)address);
  Wire.send(reg);
  Wire.send(value);
  Wire.endTransmission(); 
}

// Convert Decimal to Binary Coded Decimal (BCD)
uint8_t rtcClass::dec2bcd(uint8_t num)
{
  return ((num/10 * 16) + (num % 10));
}

// Convert Binary Coded Decimal (BCD) to Decimal
uint8_t rtcClass::bcd2dec(uint8_t num)
{
  return ((num/16 * 10) + (num % 16));
}

rtcClass RTC = rtcClass(); // create an instance for the user

Code:
/*
 * RTC.h - library for DS1307 RTC
 * This library is intended to be uses with Arduino Time.h library functions
 */

#ifndef rtcClass_h
#define rtcClass_h
#include <Time.h>    // download from http://www.arduino.cc/playground/Code/Time

// the list of supported RTC devices
enum RTCDevice_t {rtcUnknown, rtcDS1307, rtcRX8025};

// the list of interrupt intervals supported by the RX8025
enum RTCIntrInterval_t {rtcIntrDisable, rtcIntrEachSecond, rtcIntrEachMinute,rtcIntrEachHour,rtcIntrEachMonth} ; 
 
extern time_t RTCget(); //  function that can be used as a sync provider callback 
 
// library interface description

class rtcClass
{
  // user-accessible "public" interface
  public:
    rtcClass();
bool begin(RTCDevice_t device = rtcUnknown);
     //getExternalTime get;   // pointer to the get time method
time_t get();
void set(time_t t);
void read(tmElements_t &tm);
void write(tmElements_t &tm);
void setPeriodicInterrupt( RTCIntrInterval_t interval); // RX8025 only, set the periodic interrupt
void resetPeriodicInterrupt();                         // call after each interrupt to reset the pin.       
     RTCDevice_t device;  // the active device
  private:
     uint8_t address;     
bool isAddressValid(uint8_t address);
uint8_t dec2bcd(uint8_t num);
     uint8_t bcd2dec(uint8_t num);
void writeRegister( uint8_t register, uint8_t value);
};

extern rtcClass RTC;

#endif
 

49  Using Arduino / Microcontrollers / Re: can arduino uno pass the limits of its voltage (more than 9v) on: August 03, 2011, 11:17:13 pm
It depends on how much current is drawn from the 5v regulated output. And this depends on what you have connected to the pins and connected to the 5V line.  The regulator (the chip right next to the barrel connector) will get hot if you draw too much current. If that chip feels very hot when you touch it with your finger then try using a lower voltage power supply.
50  Using Arduino / Programming Questions / Re: Implementing equations on: August 03, 2011, 11:06:18 pm
It is probably the ^ that is throwing you, this is a bit wise exclusive OR.
You need
file:///Applications/Arduino.app/Contents/Resources/Java/reference/Pow.html

this might be a better link: http://www.arduino.cc/en/Reference/Pow
51  Using Arduino / Programming Questions / Re: Moved LCD to other pins and it stopted working on: August 03, 2011, 11:03:57 pm
The most likely cause is the wiring, did you check that the LCD worked after  moving the pins before adding the ethernet code?

If not,  try the sketch with the calls to  Ethernet.begin,  server.begin commented out. If you don’t see the start-up message then double check your wiring.
52  Using Arduino / Motors, Mechanics, and Power / Re: VarSpeedServo - a modified Servo library with speed control on: August 03, 2011, 10:55:28 pm
I have just come across this, nice job Korman.

Do you think this is a capability I should add to the core Servo library?

BTW, I posted an example sketch using this library here: http://arduino.cc/forum/index.php/topic,68305.msg504226.html#msg504226


53  Topics / Robotics / Re: Simultaneous but different servo sweeps with four servos on: August 03, 2011, 10:51:08 pm
here is another way to do it; using the slow speed modification to the servo library discussed in this thread: http://arduino.cc/forum/index.php/topic,61586.0.html

Code:
// speed controlled Servo Sweep
// see: http://arduino.cc/forum/index.php/topic,61586.0.html
//
// Michael Margolis 4 August 2011

#include <VarSpeedServo.h>

const int NBR_SERVOS = 4;       // the number of servos

VarSpeedServo Servos[NBR_SERVOS];        // servo objects


int servoPins[NBR_SERVOS]        = {8,     9,  10,  11}; // servo pins
int servoSpeeds[NBR_SERVOS]      = {1,    10, 100, 255}; // sweep speed, 1 is slowest, 255 fastest)
int servoMinPosition[NBR_SERVOS] = {10,   20,  30,  40}; // the minumum servo angle
int servoMaxPosition[NBR_SERVOS] = {120, 130, 140, 150}; // the maximum servo angle

void setup()
{
   for(int i=0; i < NBR_SERVOS; i++) 
   {
     Servos[i].attach(servoPins[i]);       
     Servos[i].slowmove(servoMinPosition[i],servoSpeeds[i]) ; // start sweeping from min position
   }
}

void loop()
{
  // sweep the servos
  for(int i=0; i < NBR_SERVOS; i++)
  {   
     if( Servos[i].read() == servoMinPosition[i])
       Servos[i].slowmove(servoMaxPosition[i],servoSpeeds[i]) ;         
     else if( Servos[i].read() == servoMaxPosition[i])
       Servos[i].slowmove(servoMinPosition[i],servoSpeeds[i]) ;           
  } 
}

54  Development / Other Software Development / Re: New and growing well-documented, feature-complete I2C device library on: August 03, 2011, 10:05:49 pm
... As a compromise, I've left the default at 250ms and added an optional "timeout" argument to the tail end of each read* method, so that for those specific actions that might legitimately take a long time, it's easy to specify a longer timeout. You could already have just modified the I2C::readTimeout variable before calling the desired read* method, but that's not very convenient or pretty. This is much better, and I probably should have done it that way in the first place. Yay for helpful ideas from other people!

I think having a one second default is a better idea. It won't block unless the device doesn't respond and in that case does it matter if the error is returned in one second rather than 250ms? (in the previous code, the error condition would cause it to block indefinitely)

The advantage of a longer default time-out is that inexperienced users won't get false errors when using devices that do take longer than 250ms. Experienced users can increase or decrease the time-out if they want, but it seems more friendly to have a default that minimizes the chance that errors could be reported even when the system if functioning correctly. The longer default time-out has no impact on performance on systems where the I2C devices are responding correctly.
55  Using Arduino / Sensors / Re: Best chip for frequency/pulse counting? on: August 03, 2011, 09:20:12 pm
This version should correctly return the count. I also moved the initialization code into a separate function as this can be called once only from setup.

Code:
// 16 bit timer defines added by mem to enable redifining the timer used

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#if defined(__AVR_ATmega1280__)
#define TCCRnA TCCR5A
#define TCCRnB TCCR5B
#define TCNTn  TCNT5
#define TIFRn  TIFR5
#define TOVn   TOV5
#define pulseInPin 47
#else
#define TCCRnA TCCR1A
#define TCCRnB TCCR1B
#define TCNTn  TCNT1
#define TIFRn  TIFR1
#define TOVn   TOV1
#define pulseInPin 5
#endif


void initCounter() {
  // hardware counter setup ( refer atmega168.pdf chapter 16-bit counter1)
  TCCRnA=0;     // reset timer/countern control register A
  TCCRnB=0;     // reset timer/countern control register A
  // set timer/counter1 hardware as counter , counts events on pin Tn ( arduino pin 5 on 168, pin 47 on Mega )
  // normal mode, wgm10 .. wgm13 = 0
  sbi (TCCRnB ,CS10); // External clock source on Tn pin. Clock on rising edge.
  sbi (TCCRnB ,CS11);
  sbi (TCCRnB ,CS12); 
  TCNTn = 0;
}


void startCount() {
  TCNTn=0;     // counter value = 0
  TCCRnB = TCCRnB | 7; //  Counter Clock source = pin Tn , start counting now
}

unsigned int getCount(){
  TCCRnB = TCCRnB & ~7;    // Gate Off  / Counter Tn stopped
  return TCNTn; 
}

unsigned long opengate = 0;        // the time the gate is opened
unsigned long sampletime = 2000;   // the pulse counting duration 

void setup(){
  digitalWrite(pulseInPin, HIGH); // turn on pull-ups so pin is not floating
  Serial.begin(9600);
  Serial.print("Gate time is ");
  Serial.print(sampletime);
  Serial.println(" milliseconds");
  initCounter();
  startCount();
  opengate = millis(); // open the gate ready for first count
}

void loop(){
  // check if sampletime has elapsed since gate was opened
  if( millis()- opengate  >= sampletime) {
    unsigned int pulses =  getCount();
    Serial.println(pulses); 
    startCount();
    opengate = millis(); // start over with new gate time
  }
}
56  Development / Other Software Development / Re: New and growing well-documented, feature-complete I2C device library on: August 03, 2011, 01:04:48 am
The timeout is set to a default of 250ms (defined in I2Cdev.h). Read operations that time out return -1, while 0 indicates instant failure and 1 or more indicates success. A timeout length of zero disables timeout detection.

I think that 250ms is too short for some precision I2C devices that have long sample times.
I suggest at least doubling the default  value to avoid false errors with those devices.
57  Topics / Robotics / Re: Wireless Servo Control on: August 02, 2011, 01:03:27 pm
I posted some code that my help you here: http://arduino.cc/forum/index.php/topic,67633.msg497265.html#msg497265
58  Using Arduino / Motors, Mechanics, and Power / Re: official arduino motor shield v3.0 problems on: August 02, 2011, 09:37:56 am
... and yes as you said, it seems i dont need the shield for running steppers. smiley-wink smiley-razz


you do need the shield for the steppers, its the servos that run without a shield.
59  Using Arduino / Sensors / Re: Best chip for frequency/pulse counting? on: August 02, 2011, 08:50:10 am
a minor tweak, the following two variables are no longer used and can be deleted:
  unsigned long gatetime = 0;
  int timeset = 1;


have fun!
60  Using Arduino / Microcontrollers / Re: expanding i/o ports by integrating multiple arduinos on: August 02, 2011, 06:08:36 am
you could use the arduino Mega although that is probably overkill

a nice little board with more than enough pins is the Teensy++
Pages: 1 2 3 [4] 5 6 ... 415