Balancing Robot


184 posts   Page 7 of 8   1 ... 4, 5, 6, 7, 8
by pygmy_giant » Sat Oct 06, 2012 9:57 pm
I was thinking of a hide and seek 'bot:

1) Where is sound comming from?
2) Turn towards the sound source.
3) Is there a change in the reflected ambiant IR?
4) If so - probably human - approach and ask human to confirm that it would like to play hide + seek via lcd screen (nudge robot to confirm).
5) Ask human to close eyes and count to 20.
6) Identify a location obscured from line of sight by an object.
7) Go there.
8) Wait to be discovered and nudged.
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Sun Oct 07, 2012 10:23 pm
Improved code: http://www.nsd.uk.com/miscellaneous/Ivansense_6050_test.c

Proof it works: http://www.nsd.uk.com/miscellaneous/MVI_3098.AVI

Next step to show it working on bare metal without linux...
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Mon Oct 08, 2012 3:28 pm
Ooops! fcntl.h and sys/mman.h use the operating system - so got to find an alternative method for accessing the BSCs and FIFO buffers!....
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Fri Oct 12, 2012 11:00 pm
Turns out its just a minor modification and actually easier without linux and those header files!

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3750.html

Just a minor modification...
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by morphy_richards » Sat Oct 13, 2012 5:50 am
pygmy_giant wrote:Improved code: http://www.nsd.uk.com/miscellaneous/Ivansense_6050_test.c

Proof it works: http://www.nsd.uk.com/miscellaneous/MVI_3098.AVI

Next step to show it working on bare metal without linux...

Sounds good but got a 404 Not Found from these 2 links .
User avatar
Posts: 886
Joined: Mon Mar 05, 2012 3:26 pm
Location: London
by pygmy_giant » Sun Oct 14, 2012 7:40 pm
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Sun Oct 14, 2012 8:44 pm
Dodgey vid to demonstrate operation: http://www.njbsmith.net/miscellaneous/MVI_3111.AVI I have added an LCD - this should enable communication from the control system and aid debugging once fully headless....
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Mon Oct 15, 2012 3:17 pm
Think I will give ChibiOS a go this weekend: http://www.stevebate.net/chibios-rpi/GettingStarted.html
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by mikejr » Sat Oct 27, 2012 2:40 pm
Thanks to this thread I have my RasPi talking to my MPU6050.
I have tried to write a minimal make file for Raspi and MPU6050.
Code: Select all
#
# Makefile:
# MKB:2012/10/27
#   My attempt at making a minimal makefile to use as a
#   starting point for RasPi and MPU-6050

#   What is the name of your program?
NAME   =   main

CC      =   gcc
CFLAGS   =   -Wall
LIBS   =   -lm

SRC      =   $(NAME).c
OBJ      =   $(NAME).o
BINS   =   $(NAME)

main:   $(OBJ)
   @echo [link]
   $(CC) -o $@ $^ $(LIBS)

%.o : %.c
   @echo [CC] $<
   @$(CC) -c $(CFLAGS) $< -o $@

clean:
   rm -f $(OBJ) *~ core $(BINS)

I hope this helps someone and I welcome all comments.
Trying to give back.
Thanks to all.
Mike
Posts: 15
Joined: Sat Oct 27, 2012 2:26 pm
by almarlow » Tue Oct 30, 2012 4:40 am
Hi,

Thanks for this forum. You've inspired me to have a go at putting a self balancing robot together.

I had managed to get an MPU-6050 talking to my Revision A Raspberry Pi using the code you've posted earlier in this thread. However, on the new Revision B board I just got, it stopped working - failing on the test of the MPU6050_RA_WHO_AM_I register returning 0x68. On the new board it kept returning 0x152.

Because the Revision B boards have swapped the I2C devices that appear on the main connector and the other connector, the code needed to refer to BSC-1 rather than BSC-0. I found the relevant memory address details on p26 of the Broadcom BCM2835 Datasheet:
• BSC0: 0x7E20_5000
• BSC1: 0x7E80_4000

The line of code that needed to be changed was:
#define BSC0_BASE (IOBASE + 0x205000)
and it needed to be changed to:
#define BSC0_BASE (IOBASE + 0x804000)

I've implemented this as a one time change to the code but it could be worth adding some code that allows selection of which address to use based on the board Revision, or test both to see which BSC the MPU-6050 is connected to.

Hope this saves someone some time in tracking down an answer to this problem.
Posts: 6
Joined: Thu Aug 02, 2012 12:47 am
by garym1957 » Sat Nov 03, 2012 5:00 am
Wait... You have a working program?
I cant get the patches loaded as described in some of the docs. http://wiki.analog.com/resources/tools- ... ed_example

I can get the i2cdetect -y 0 to report hex 53 which I believe is a good thing?

Please take the time to write something for those of us who need a leg up. Maybe some kind of command-line demo or something. Please? I have spent about 10 hours trying to educate myself enough to get a reading from the ADXL345 but I can't tell where I am.

Can you tell me what kernel and distro I need? What drivers and what does the wiring look like?

All i know is modprobe adxl34x does NOTHING that I can tell. From the examples it appears to work for everyone else.
Posts: 11
Joined: Fri Aug 24, 2012 6:04 am
by almarlow » Sat Nov 03, 2012 10:12 am
Hi garym,

The program I have working is the Ivansense_6050_test.c program that pygmy_giant posted a link to in a previous post. It' set up to drive the MPU-6050 accelerometer/gyroscope. I don't have the ADXL345 accelerometer that you're trying to use so I doubt I can offer to much help on that device.

almarlow
Posts: 6
Joined: Thu Aug 02, 2012 12:47 am
by joan » Sat Nov 03, 2012 12:53 pm
garym1957 wrote:Wait... You have a working program?
...

I don't use the adxl345 module. I just use the i2c bus.

Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>

#define SRF02_I2C_ADDR    0x70
#define ADXL345_I2C_ADDR  0x53
#define HMC5883L_I2C_ADDR 0x1E
#define ITG3200_I2C_ADDR  0x68

#define MOTOR_1 4
#define LASER   5
#define MOTOR_2 6
#define PIR     7

void selectDevice(int fd, int addr, char * name)
{
   if (ioctl(fd, I2C_SLAVE, addr) < 0)
   {
      fprintf(stderr, "%s not present\n", name);
   }
}

void writeToDevice(int fd, char * buf, int len)
{
   if (write(fd, buf, len) != len)
   {
      fprintf(stderr, "Can't write to device\n");
   }
}

int main(int argc, char **argv)
{
   unsigned int range;
   int count, b;
   short x, y, z;
   float xa, ya, za;
   int fd, mygpio;
   char intruder;
   unsigned char buf[16];
   
   if ((fd = open("/dev/i2c-0", O_RDWR)) < 0)
   {
      // Open port for reading and writing
      perror("Failed to open i2c bus");
      exit(1);
   }
   
   /* initialise ADXL345 */

   selectDevice(fd, ADXL345_I2C_ADDR, "ADXL345");

   writeToDevice(fd, "\x2d\x00", 2);
   writeToDevice(fd, "\x2d\x10", 2);
   writeToDevice(fd, "\x2d\x08", 2);
   writeToDevice(fd, "\x31\x00", 2);
   writeToDevice(fd, "\x31\x0b", 2);

   /* initialise HMC5883L */

   selectDevice(fd, HMC5883L_I2C_ADDR, "HMC5883L");

   writeToDevice(fd, "\x02\x00", 2);

   /* initialise ITG3200 */

   selectDevice(fd, ITG3200_I2C_ADDR, "ITG3200");

   writeToDevice(fd, "\x16\b00011000", 2);

   while (1)
   {   
      selectDevice(fd, SRF02_I2C_ADDR, "SRF02");

      writeToDevice(fd, "\x00\x51", 2);
   
      usleep(100000);  // wait long enough to ensure ping
   
      writeToDevice(fd, "\x00", 1);
   
      if (read(fd, buf, 4) != 4)
      {
         fprintf(stderr, "Can't read from SRF02\n");
      }
      else
      {
         range = buf[2]<<8 | buf[3];
         printf("%3u ", range);
      }

      selectDevice(fd, ITG3200_I2C_ADDR, "ITG3200");

      writeToDevice(fd, "\x1D", 1);
   
      if (read(fd, buf, 6) != 6)
      {
         //  X, Y, Z accelerations

         fprintf(stderr, "Unable to read from ITG3200\n");
      }
      else
      {
         x = buf[1]<<8| buf[0];
         y = buf[3]<<8| buf[2];
         z = buf[5]<<8| buf[4];
         xa = (90.0 / 256.0) * (float) x;
         ya = (90.0 / 256.0) * (float) y;
         za = (90.0 / 256.0) * (float) z;
         //printf("x=%d, y=%d, z=%d\n", x, y, z);
         //printf("%4.0f %4.0f %4.0f", xa, ya, za);
         printf("ITG: "); for (b=0; b<6; b++) printf("%02x ", buf[b]);
      }


      selectDevice(fd, HMC5883L_I2C_ADDR, "HMC5883L");

      writeToDevice(fd, "\x03", 1);
   
      if (read(fd, buf, 6) != 6)
      {
         //  X, Y, Z accelerations

         fprintf(stderr, "Unable to read from HMC5883L\n");
      }
      else
      {
         x = buf[1]<<8| buf[0];
         y = buf[3]<<8| buf[2];
         z = buf[5]<<8| buf[4];
         xa = (90.0 / 256.0) * (float) x;
         ya = (90.0 / 256.0) * (float) y;
         za = (90.0 / 256.0) * (float) z;
         //printf("x=%d, y=%d, z=%d\n", x, y, z);
         //printf("%4.0f %4.0f %4.0f", xa, ya, za);
         printf("HMC: "); for (b=0; b<6; b++) printf("%02x ", buf[b]);
      }


      selectDevice(fd, ADXL345_I2C_ADDR, "ADXL345");

      writeToDevice(fd, "\x32", 1);
   
      if (read(fd, buf, 6) != 6)
      {
         //  X, Y, Z accelerations

         fprintf(stderr, "Unable to read from ADXL345\n");
      }
      else
      {
         x = buf[1]<<8| buf[0];
         y = buf[3]<<8| buf[2];
         z = buf[5]<<8| buf[4];
         xa = (90.0 / 256.0) * (float) x;
         ya = (90.0 / 256.0) * (float) y;
         za = (90.0 / 256.0) * (float) z;
         //printf("x=%d, y=%d, z=%d\n", x, y, z);
         printf("ADXL %4.0f %4.0f %4.0f", xa, ya, za);
         //for (b=0; b<6; b++) printf("%02x ",buf[b]); printf("\n");
      }


      /* read the PIR (digital HIGH for alarm) */
      if ((mygpio = open("/dev/mygpio0", O_RDWR)) < 0)
      {
         // Open port for reading and writing
         fprintf(stderr, "Failed to open mygpio device\n");
      }
      else
      {
         sprintf(buf, "r %d", PIR); /* read PIR */
         write(mygpio, buf, 3);
         read(mygpio, buf, 1); /* get PIR value */
         printf(" %c", buf[0]);

         intruder = buf[0];

         /* set laser state */
         sprintf(buf, "w %d %c", LASER, intruder);
         write(mygpio, buf, 5);

         /* set motor_1 state */
         sprintf(buf, "w %d %c", MOTOR_1, intruder);
         write(mygpio, buf, 5);

         /* set motor_2 state */
         sprintf(buf, "w %d %c", MOTOR_2, intruder);
         write(mygpio, buf, 5);

         close(mygpio);
      }

      printf("\n");

      usleep(100000);
   }
   
   return 0;
}


Compile with

cc -o sensors sensors.c

Run with

./sensors

Ignore the errors about missing devices and mygpio. It should report readings from the ADXL345.

If the source code doesn't compile it may be because the forum cut and paste facility is borked.

Try

tr -d "\240\302" <sensors.c >sensors2.c

which may remove extraneous characters and will place the new source in sensors2.c
User avatar
Posts: 6372
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by mikejr » Sat Nov 03, 2012 2:13 pm
I have tried to write I2C and MPU6050 libraries"?" or modules. Noob doesn't know. :)
Just the I2C
main01.tar
(20 KiB) Downloaded 89 times

Both I2C and MPU6050
main02.tar
(30 KiB) Downloaded 130 times


Thanks to all.
Hope this helps someone.
I welcome feedback.
Mike
Posts: 15
Joined: Sat Oct 27, 2012 2:26 pm
by pygmy_giant » Sat Nov 03, 2012 2:17 pm
interesting.

I'm making slow progress with mine at the moment

My daliance with ChibiOS ended in catastrophe and so I'm toying with the idea of using GCC and RISCOS as there wont be annoyin interuptions from Linux and it won't obstruct my attempts to access memory directly.

I am even wondering whether BASIC could be fast enough as the interprater runs in cache.

Anyway, my son painted the bot silver and I added a keypad and screen:

Image
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by garym1957 » Sat Nov 03, 2012 2:49 pm
joan wrote:
garym1957 wrote:Wait... You have a working program?

I don't use the adxl345 module. I just use the i2c bus....


OMG Thank you!!! It works!. I commented out half the program but now I can get clean output..
What was I DOING? There are so many crummy examples out there that start with recompiling the kernel and rebuilding this or that library - followed by depression and suicide heheh... It took - not kidding here - 60 seconds to get your program compiled and running. Awesome.

Whats this in the code? You have a PIR device that speaks i2c?

Whoever you are, God bless you. Thank you very much.
Posts: 11
Joined: Fri Aug 24, 2012 6:04 am
by Frank B » Sat Nov 03, 2012 8:46 pm
pygmy_giant wrote:interesting.

I'm making slow progress with mine at the moment

My daliance with ChibiOS ended in catastrophe and so I'm toying with the idea of using GCC and RISCOS as there wont be annoyin interuptions from Linux and it won't obstruct my attempts to access memory directly.

I am even wondering whether BASIC could be fast enough as the interprater runs in cache.

Anyway, my son painted the bot silver and I added a keypad and screen:

Hi,
my progress is slow too. Currently i'm playing with ultrasonic sensors and i have a webcam & servo laying around...
My remote-control is working now. Maybe i post a new video next weekend.

As i said before, you can use Linux without any problem. Why don't you give it a try ? It works like a charm. I do not notice any "interruptions" from linux. You can run apt-get update...while "roberta" is balancing and "dancing" :-) (I bought her new "shoes", and she likes them...:-) But she needs a nice "dress" like your bot...)

Just use the MPU-Interrupt-Pin and connect it to one of the GPIOS.
Or use the micro on youre expansion-board...
Posts: 61
Joined: Fri Sep 14, 2012 8:02 pm
Location: Germany
by pygmy_giant » Sat Nov 03, 2012 8:53 pm
may do...pleased to see that all the pooh-pooh-ing nay-saying doom-mongers were wrong :D

what does the 'MPU-Interrupt-Pin' do? Is it the 'int' pin on the 6050?

look forward to seeing your video - how did those encoders work out?
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by Frank B » Sat Nov 03, 2012 9:06 pm
pygmy_giant wrote:may do...pleased to see that all the pooh-pooh-ing nay-saying doom-mongers were wrong :D

They are wrong.
pygmy_giant wrote:what does the 'MPU-Interrupt-Pin' do? Is it the 'int' pin on the 6050?

Yes.
pygmy_giant wrote:look forward to seeing your video - how did those encoders work out?

[/quote]
Uh.. that was a bit tricky. At first,i had too much current for the IR-transmitter-LEDs and it was difficult to detect the black marks. Now they work. Not perfect,but ok. I spent some hours on this.
Posts: 61
Joined: Fri Sep 14, 2012 8:02 pm
Location: Germany
by pygmy_giant » Sun Nov 04, 2012 4:37 am
Yes - it's impossible to see how bright IR LEDs are but you can actually see the light if you view them through a digital camera.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Tue Nov 06, 2012 10:22 pm
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by mikejr » Thu Nov 08, 2012 1:33 am
Thank you rgh and pygmy_giant for pointing out this thread. This IS the way to learn C/C++ programming
Awesome!

Thanks,
Mike
Posts: 15
Joined: Sat Oct 27, 2012 2:26 pm
by pygmy_giant » Tue Nov 13, 2012 1:15 pm
This thread demonstrates that GCC works on RISCOS: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=55&t=22783 I'm hoping to use this for my control code as I think it will interupt less than Linux
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by mikejr » Wed Nov 21, 2012 5:56 pm
I have been working on converting Adafruit python code to cpp. Adafruit 16ch PWM.
Raspberry Pi + MPU6050 + PCA9685 + I2Cdev = cool. :-)
Servo moves relative to MPU6050 angle.
Here is my progress so far.
Servo.tar.zip
(33.61 KiB) Downloaded 102 times

I don't know what "reset" does. I would like to stop sending a signal to the servos when my program ends. I guess I need to read the PCA9685 pdf a few more times.

Hopefully this helps someone. However, I am an amateur.
Thanks for the help.
Mike
Posts: 15
Joined: Sat Oct 27, 2012 2:26 pm
by pygmy_giant » Sat Nov 24, 2012 1:04 pm
Good work - might adapt it!

I am becomming more convinced that RISCOS is for me the way to go: http://www.riscosopen.org/wiki/documentation/show/Software%20information:%20RTSupport

I suspect that RISCOS +GCC could be responsive enough even for a quadcopter.

Im wondering whether something along the lines of

_swix(0x7b,address,data,1 or 4);

might work in C using UnixLib under RISCOS for I2C transfer?
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am