Show Posts
Pages: [1] 2 3 4
1  Using Arduino / Programming Questions / Re: boolean return values from base classes not returning up through child classes on: September 27, 2014, 11:02:12 pm
Thank you for your guidance. I've made the changes in the code and it seems to be working and cleaner.
2  Using Arduino / Programming Questions / Re: boolean return values from base classes not returning up through child classes on: September 27, 2014, 07:48:55 pm
Hello guys.

Thanks for your help.

I didn't write BMSerial or Roboclaw, so I have no idea why they were done that way. It's what the manufacturer provided.

I think I found the problem. The RoboClaw class always returns 'false' on methods involving 'writes' to the controller but 'true/false' if 'reading' from the controller. (Unless 'ack' is set to true when initializing the RoboClaw class.) See bool RoboClaw::write_n(uint8_t cnt, ... ) in the RoboClaw.cpp file.

I've made the following change to the code:
Code:
// set ACK to true to get 'write' methods to return useful booleans.
RoboClaw mc(10,11,10000,true);

As to the usage of the '->' operator, I couldn't get it to compile if I didn't use it. I don't know C++ that well.

For example here's some of my original code:
Code:
      valid = this->RCmc->SetM2VelocityPID(
                this->rcAddress,
                this->rightMotor.D,
                this->rightMotor.P,
                this->rightMotor.I,
                this->rightMotor.qpps);

I can clean it up a bit to:
Code:
      valid = ROSArdRoboclaw::RCmc->SetM2VelocityPID(
                ROSArdRoboclaw::rcAddress,
                ROSArdRoboclaw::rightMotor.D,
                ROSArdRoboclaw::rightMotor.P,
                ROSArdRoboclaw::rightMotor.I,
                ROSArdRoboclaw::rightMotor.qpps);
and it still works correctly and compiles, but I don't know how to get rid of the one remaining "->" between "RCmc->SetM2VelocityPID"

The things I try fail to compile:

Code:
      valid = ROSArdRoboclaw::RCmc::SetM2VelocityPID(...);
//
ROSArdRoboclaw.cpp: In member function 'bool ROSArdRoboclaw::sendPIDtoRC(int)':
ROSArdRoboclaw.cpp:203: error: 'ROSArdRoboclaw::RCmc' is not a class or namespace

or
Code:
      valid = ROSArdRoboclaw::RCmc.SetM2VelocityPID(...);
// ROSArdRoboclaw.cpp: In member function 'bool ROSArdRoboclaw::sendPIDtoRC(int)':
ROSArdRoboclaw.cpp:203: error: request for member 'SetM2VelocityPID' in '((ROSArdRoboclaw*)this)->ROSArdRoboclaw::RCmc', which is of non-class type 'RoboClaw*'

I'm all for doing it the 'right' way. Please let me know how.
3  Using Arduino / Programming Questions / Re: boolean return values from base classes not returning up through child classes on: September 27, 2014, 07:02:44 pm
Weird. I've attached BMSerial and RoboClaw libraries as their individual components.

Full packages with all examples from RoboClaw
4  Using Arduino / Programming Questions / Re: boolean return values from base classes not returning up through child classes on: September 27, 2014, 06:31:18 pm
Full code as it currently exists attached. My code is in 'code.zip'. BMSerial and RoboClaw libraries in RoboClaw.zip
5  Using Arduino / Programming Questions / boolean return values from base classes not returning up through child classes on: September 27, 2014, 06:14:44 pm
In my wrapper class I have:
Code:
//  (ROSArdbase is an abstract class. The idea is to have separate children classes for each type of motor controller.)
class ROSArdRoboclaw: public ROSArdBase {
  public:
    int rcAddress;     // address of the controller.
    RoboClaw *RCmc;    // instance of the RoboClaw controller object.

  public:
    ROSArdRoboclaw(RoboClaw *mc, int address, long baud)  {
      this->RCmc = mc;              // instance of RoboClaw class
      this->rcAddress = address;    // address of RoboClaw (allow use of multiple controllers)
      this->cbBaud = baud;          // set controller board baud rate. (Between Arduino and RoboClaw)
    }
    bool getPIDfromRC(VPID *p, int motor);   // retrieve settings actually on RoboClaw

...snip...

In main sketch I first initialize an instance of the RoboClaw controller with:
Code:
#include "ROSArdRoboclaw.h"
#include "BMSerial.h"
#include "RoboClaw.h"

// set up roboclaw object on RX 10, TX 11 with 10ms of timeout (between Arduino and RC)
RoboClaw mc(10,11,10000);

// and then pass this object to my wrapper class:
ROSArdRoboclaw bot(&mc,0x80,38400);

Everything 'works' Commands that I execute through the wrapper class are passed to the motor controller and executed as expected. For example the getPIDfromRC method correctly returns values into the VPID structure, as well as all other methods that I've wrapped.

What's not working is that boolean values from the various base RoboClaw methods are not 'rippling' up.

For example, one of my wrapper methods is:
Code:
bool ROSArdRoboclaw::getPIDfromRC(VPID *p, int motor) {
    bool valid;
    if (motor == LEFT) {
      // valid should be 1, but is always 0, even though I've confirmed that this
      // command is executing and reading values correctly !!!
      valid = this->RCmc->ReadM1VelocityPID(this->rcAddress, p->P,p->I,p->D,p->qpps);
    } else if (motor == RIGHT) {
      valid = this->RCmc->ReadM2VelocityPID(this->rcAddress, p->P,p->I,p->D,p->qpps);
    } else {
      return false;
    }
    return valid;
}
but even though ReadM1VelocityPID is executed successfully on the motor controller, the boolean 'true' value it's returning is not making its way into 'valid'

In the RoboClaw.h we see that it should be returning a 'true' upon success:
Code:
.h
bool ReadM1VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps);
bool ReadM2VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps);

.cpp

bool RoboClaw::ReadM1VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps){
uint32_t Kp,Ki,Kd;
bool valid = read_n(4,address,READM1PID,&Kp,&Ki,&Kd,&qpps);
Kp_fp = ((float)Kp)/65536;
Ki_fp = ((float)Ki)/65536;
Kd_fp = ((float)Kd)/65536;
return valid;
}

I've confirmed that if I just use the motor controller instance 'mc' established at the beginning of the sketch rather than through my wrapper class, it ~does~ return the correct BOOL value upon success.

For example:
Code:
valid = mc.ReadM1VelocityPID(0x80,test2.P,test2.I,test2.D,test2.qpps);
results in valid being set to '1' which is the expected result as well as returning the same values for the PID as my wrapper method does.

Question. Why is the boolean value from the RoboClaw method not making it's way up through my wrapper object???

I'd like to be able to test for valid execution of commands just as I can if accessing the motor controller object directly.
6  Using Arduino / Programming Questions / Re: Control DC motors? on: September 23, 2014, 07:56:20 pm
That way of using your motor is not going to work (most likely). The Arduino can not source enough power for a motor. The power supply should be separate from the Arduino !!

Try something like this instead. You need to provide a separate power supply for the motor and at the correct voltage. (The motor may not be a 5V motor, you didn't specify.)

As an aside, you should check out Fritzing. They have plenty of layouts for hundreds of simple projects.

7  Using Arduino / Programming Questions / Re: Arduino RF comunication on: September 23, 2014, 07:38:21 pm
You'll need to provide a bit more information.

Primarily, what kind of RF receivers and transmitters are you using.

Also, a casual glance for VirtualWire library indicates that it is deprecated and that a different library should be used. I'd recommend trying with the new library and walking through the examples given there, implementing the correct ones based on the particular type of radios you have.
8  Using Arduino / Programming Questions / Re: Overload is ambiguous error. How to work around this? on: September 23, 2014, 07:32:13 pm
Yes.  Thank you.

removing the default values is the correct answer:

Code:
class Shape {
   protected:
      float width, height, radius;
   public:
      Shape( float r) {
        radius = r;
      }
      Shape( float a, float b) {
         width = a;
         height = b;
      }

PS. This class was just a gross simplification of the actual code which has nothing to do with 'shapes', but rather robotic motor controllers. I'm attempting to build an abstract base class for the controllers. There will be child classes for each particular type of implemented controller (RoboClaw, Pololu, RoboTEQ, etc.) that will inherit and/or be forced to implement methods of the base class, thus part of the reason for overloaded Constructors.

As an aside, allowing for default values can be implemented in the child classes as I've discovered.
9  Using Arduino / Programming Questions / Re: Control DC motors? on: September 23, 2014, 12:54:20 am
DC motors are typically controlled with a H-Bridge Motor controller chips or shields.

Although you mention a transistor and diode, you don't provide enough information. For example, are you trying to power the motor from the Arduino? (bad idea). Do you have a the transistor rigged correctly?

As another poster has mentioned, you might want to try getting a LED to stand in for the motor to see if your circuit is working. 

Really though, you should get either an H-Bridge chip or motor shield. Ultimately that's the way to go with controlling DC motors.
10  Using Arduino / Programming Questions / Re: Filling an array on one line {a,b,c,d} on: September 22, 2014, 09:05:06 pm
Code:
int sizeOfArray = 5;
int test[] = {1,2,3,4,5};

void setup(){
 // one line implementation of loading the array
  for (int i=0;i<sizeOfArray;i++) {test[i] = digitalRead(i);  }
};

Or something like that. I think where you're getting confused is in the construction of the array and its initialization.

It's a convenience afforded by the compiler that you can do both at the same time:
Code:
int array[] = [1,2,3,4,5];

rather than:

int array[5]; // allocate memory for 5 ints
array[0] = 1;
array[1] = 2;
...
array[4] = 5;
Really what's happening is that you're telling the compiler to initialize an array with 5 elements and 'oh by the way' here are the 5 things I want to start with.

Later when you use 'array' what you really have is an address pointing to the beginning of the array. The code and compiler at that point have no idea how long 'array' is. Could be 5 elements long, could be 500. To see what I mean try this code:

Code:
int sizeOfArray = 8; // I've intentionally set this value higher than what is allocated to test below.
int test[] = {1,2,3,4,5};

void setup(){
  Serial.begin(57600);
  for (int i=0;i<sizeOfArray;i++) {
    Serial.print(test[i],DEC);
    Serial.print(",");
  }
};

void loop(){

}

You'll end up with something like "1,2,3,4,5,684,328,206" where the last three 'entries' of the array are some garbage. The compiler doesn't know that the array is only 5 'int' elements long, and will happily read the next three memory locations in 'int' sized increments and spit them out at you.

This is where memory leaks and other nasty things come from. C is a very powerful language, but it's also very sparse and doesn't 'protect' you like some other higher level languages you might have used before do.

This is related to why you can't use the same 'initialization' method later on to just file the array as you'd like to.
11  Using Arduino / Programming Questions / Overload is ambiguous error. How to work around this? on: September 22, 2014, 08:26:59 pm
I'm trying to create a base class. I'd like to be able to instantiate the class several different ways but am getting the 'overload is ambiguous error'

Here's a simple class to illustrate. I'd like to be able to instantiate Shapes that either have width/heights or radius

Code:
class Shape {
   protected:
      float width, height, radius;
   public:
      Shape( float r=0) {
        radius = r;
      }
      Shape( float a=0, float b=0) {
         width = a;
         height = b;
      }

      // pure virtual function
      virtual float area() = 0;
};

class Circle: public Shape{
   public:
      Circle(float r=0): Shape(r) {}
      float area();
};
class Rectangle: public Shape{
   public:
      Rectangle( float a=0, float b=0):Shape(a, b) { }
      float area();
};

When "Circle" builds off of "Shape", I get the following error:

Code:
Circle.h:7: error: call of overloaded 'Shape(float&)' is ambiguous
shape.h:12: note: candidates are: Shape::Shape(float, float)
shape.h:9: note:                 Shape::Shape(float)
shape.h:5: note:                 Shape::Shape(const Shape&)

Of course, if I change one of the class constructors to be "int" and leave the other "float", it works. For example this works but at the expensive of not having the type I want for one of the constructors:

Code:
class Shape {
   protected:
      float width, height;
      int radius;
   public:
   Shape( int r=0) {
        radius = r;
      }
      Shape( float a=0, float b=0) {
         width = a;
         height = b;
      }

Question: How do I build the base class overload constructors so that both (or many) can share the same numeric type?
12  Topics / Robotics / Re: Simple (?) SLAM created map on: September 22, 2014, 08:09:46 pm
SLAM (simple or otherwise) is higher on the stack than coding for Arduino.

A good place to look for useful implementations of this would be on the ROS Documentation Wiki . This link show may examples and implementations.

I doubt you're going to get any form of SLAM working just on a microcontroller.  Rather, you'll use the microcontroller to gather sensor data and/or drive the wheels of the robot and a full stack computer will implement the SLAM algorithms. In other words, the Arduino will probably only tangentially be involved in the SLAM algorithm either in a data acquisition mode or executing wheel commands.


13  Using Arduino / Networking, Protocols, and Devices / Tiny RTC - Battery Monitor pin - power drain on: August 16, 2013, 12:54:19 pm
I'm using one of these http://www.hobbyist.co.nz/?q=real_time_clock

When I attach the Battery Pin to an analog pin on an Uno, I can read the voltage of the battery. That's kind of cool.

The problem is, if you remove the power from the Uno, it seems like power drains from the RTC module to the Arduino, causing a significant voltage drop on the RTC device and thus 'loosing' it's time setting. (Voltage drops below 1v on the RTC device where it is normally closer to 3.3v)

I've reverted my project back to not monitoring the Battery Level, but it seems like there must be a way to do this: Allow monitoring of the battery level if and only if the Arduino has power. On power outage, prevent the battery from draining through the analog pin.

My first thoughts were to put a transistor between the pins such that the transistor was 'on' only when Arduino is powered and otherwise off.

Any other thoughts on how to handle this?
14  Using Arduino / Networking, Protocols, and Devices / Re: RTClib problems - Ethernet w/SD card + OneWire + DallasTempurature on: August 14, 2013, 07:23:53 pm
Bingo.

I had a 5V power supply into the power barrel

Bumped it to 12V and now everything seems to work. (Will drop it to a 9V as soon as I find one to lower power dissipation..)

Thanks.

If you have a moment, can you explain why this is making a difference? I'm assuming that it's because the power inverter was reducing the voltage slightly from 5 to < 5.  If you can confirm that would be great.

Thanks for your time.
15  Using Arduino / Networking, Protocols, and Devices / RTClib problems - Ethernet w/SD card + OneWire + DallasTempurature on: August 14, 2013, 05:24:48 pm
I'm using the following to build a temperature logger and, ultimately, controller.
  • Adruino UNO and software 1.0.4
  • Ethernet Shield with integrated SD card
  • Tiny RTC breakout board
  • OneWire DS18B20 temperature ICs
  • SanDisk 2GB micro SD card

To get everything running, I'm importing the following libraries.

Code:
#include <Wire.h>
#include "RTClib.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Fat16.h>
#include <Fat16util.h>

The Arduino reads the sensors and if the temperature has changed, it logs the time and temperature reading to the 2GB micro SD card.

The good news is that when I monitor everything via the USB serial port "Serial Monitor" everything works as expected. I can see the updates via the serial monitor, the code is successfully logging the information to the SD card, and I can poll the device over the Ethernet and retrieve the current temperatures as JSON.

Sample from data stored on the SD card when everything is working and the Arduino is tethered to my computer via a USB cable
Code:
1376477404,2013-8-14 10:50:4,77.90,76.10,75.20
1376484172,2013-8-14 12:42:52,78.80,77.00,77.00
1376484711,2013-8-14 12:51:51,78.80,77.90,77.00
1376485722,2013-8-14 13:8:42,79.70,77.90,77.00
1376489582,2013-8-14 14:13:2,80.60,78.80,78.80

Now, the problem I'm having is that when I disconnect the USB cable from the Arduino, all hell breaks loose. To start with the RTC seems to start returning a spurious result, basically, I get a unix timestamp value of '2212184785' constantly, which isn't even a legal value.

It seems like the Ethernet library, the OneWire/Dallas Tempurature libraries are working, and the SD card library is working, but for some reason the values reported by the RTC are junk.

Here's what on the SD card if I boot the code without being tethered. The Unix Timestamp (first value) and the Date/Time (second value) are completely wrong and do not change from moment to moment.
Code:
2212184785,2165-165-165 165:165:85,82.40,80.60,59.90
2212184785,2165-165-165 165:165:85,82.40,80.60,62.60
2212184785,2165-165-165 165:165:85,82.40,80.60,64.40

The JSON from the Ethernet connection also reports this incorrect time, but does export the correct temperature values. And more importantly, shows that the Ethernet Lib continues to work:
Code:
{"UTC":"2212184785","tf0":"82.40","tf1":"80.60","tf2":"62.60","avg":"75.20"}

I've tried compiling a version of the code with ALL calls to any Serial or Serial related functions commented out. This yields the same result, basically, the RTC doesn't seem to work. (It works if the USB cable is plugged in even though there's no serial connection. It doesn't work once the USB cable is untethered.)

I've got the RTC break out board plugged into the Analog Pins. A5 = SCL, A4 = SDA, A3 = HIGH = 5v power, A2 = LOW = Ground, A1 = BAT = Unused. See attached image.

Any ideas on why untethering from the USB would cause the TinyRTC breakout board and library to start returning crap values?
My suspicion is that it has something to do with the Wire Library and perhaps some interaction with the Ethernet Shield w/integrated SD card. ???

Attached is my code with all the calls to Serial stripped out.

When running the version ~with~ the Serial calls left in, I have free RAM of 563 bytes. (This is when Arduino is attached via USB to computer and all code is working correctly.)
Pages: [1] 2 3 4