[Resolved]Unable to open I2C bus

Home Forums Forums Technical Support for BerryIMU [Resolved]Unable to open I2C bus

Viewing 15 posts - 16 through 30 (of 36 total)
  • Author
    Posts
  • #3980
    jawood
    Participant

    yeah tried that no change same error

    #3982
    Mark Williams
    Keymaster

    try this;
    sudo apt-get install libi2c-dev

    the recompile

    Mark --OzzMaker.com --

    #3983
    jawood
    Participant

    sudo apt-get install libi2c-dev
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    libi2c-dev is already the newest version.
    0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.

    #3985
    Mark Williams
    Keymaster

    When you copy the text of the web page.. some of the commands are converted.
    I changed how the text is shown in the web page.

    Refresh the instructions and hey copy the compile statement again.

    Or, view the README in the folder for the correct compile statement

    Mark --OzzMaker.com --

    #3986
    jawood
    Participant

    gcc -o gyro_accelerometer_tutorial02 -lm gyro_accelerometer_tutorial02.c sdl-config --cflags sdl-config --libs -lSDL_image -lSDL_gfx
    gyro_accelerometer_tutorial02.c: In function ‘startSDL’:
    gyro_accelerometer_tutorial02.c:217:19: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
    gyro_accelerometer_tutorial02.c: In function ‘graphics’:
    gyro_accelerometer_tutorial02.c:280:38: warning: assignment makes pointer from integer without a cast [enabled by default]
    gyro_accelerometer_tutorial02.c:281:39: warning: assignment makes pointer from integer without a cast [enabled by default]

    sudo ./gyro_accelerometer_tutorial02 It Works!!!! So cool!!!!

    Want to use this as a leveller for my Caravan connected to 4 worm shafts to auto level the Van. (I think the update rate is going to be to slow thou.)

    Thou it is working now it is quite slow to update and appears to be slightly out of calibration when on a flat level surface after a second or so when it stabilize I have to hold the unit at about 10 degrees off flat on the left/right axis to show flat on the PiScreen, front to back seems to be ok.

    #3987
    jawood
    Participant

    Ow one other thing I would love to be able to run it as a full screen app, so you cant see the task bar or anything else. Would appreciate some advise on how to do that!

    And thanks for all your help getting it going!

    #3988
    Mark Williams
    Keymaster

    play around with the complimentary filter constant
    #define AA 0.97 // complementary filter constant
    This controls how much of the gyro or the accelerometer is used in the fused angle.
    lowering the value will result in a faster correct angle result.

    Regarding speed;
    If you are using a PiScreen to display this output, try increasing the speed the PiScreen by changing the speed value in /boot/config.txt

    dtoverlay=piscreen,speed=16000000,rotate=90

    try 32000000.. if the colors dont look right, try 24000000. You will have to reboot to for the change to take effect.

    You can also try lowering the delay in the loop;
    #define DT 0.2 // loop period. 0.2 = 200ms
    It is currently set to 200ms… remember that you need to keep a constant loop time, otherwise your gyro angle will drift too much. The loop time is the first value printed out to the console.

    Mark --OzzMaker.com --

    #3989
    jawood
    Participant

    thanks for the sugestions I was wondering if adding the kalman filter would make it a bit better. I had a look and it seems pretty straight forward to add it.

    I think change this graphics(CFangleX,CFangleY); to graphics(kalmanX,kalmanY); and add the functions variables etc..

    #3991
    jawood
    Participant

    I think this should do it. Whats in bold I added.

    /*

    This program is used to create an Inclinometer using a
    Raspberry Pi and an IMU

    https://ozzmaker.com/2014/12/12/inclinometer-using-raspberry-pi-imu/

    Copyright (C) 2014 Mark Williams

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place – Suite 330, Boston,
    MA 02111-1307, USA
    */

    #include “SDL.h”
    #include “SDL/SDL_image.h”
    #include <unistd.h>
    #include <math.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <string.h>
    #include <time.h>
    #include “sensor.c”

    #define DT 0.2 // loop period. 0.2 = 200ms
    #define AA 0.97 // complementary filter constant

    #define A_GAIN 0.0573 // [deg/LSB]
    #define G_GAIN 0.070 // [deg/s/LSB]
    #define RAD_TO_DEG 57.29578
    #define M_PI 3.14159265358979323846

    //Used by Kalman Filters
    float Q_angle = 0.01;
    float Q_gyro = 0.0003;
    float R_angle = 0.01;
    float x_bias = 0;
    float y_bias = 0;
    float XP_00 = 0, XP_01 = 0, XP_10 = 0, XP_11 = 0;
    float YP_00 = 0, YP_01 = 0, YP_10 = 0, YP_11 = 0;
    float KFangleX = 0.0;
    float KFangleY = 0.0;

    float kalmanFilterX(float accAngle, float gyroRate);
    float kalmanFilterY(float accAngle, float gyroRate);

    int graphics(float carRoll, float carPitch);
    int startSDL();
    SDL_Surface* screen = NULL;
    SDL_Surface* inclinometerJeepFront = NULL;
    SDL_Surface* inclinometerJeepSide = NULL;
    SDL_Surface* inclinometerOverlay = NULL;
    SDL_Surface* compatibleInclinometerJeepFront = NULL;
    SDL_Surface* compatibleInclinometerJeepSide = NULL;
    SDL_Surface* compatibleInclinometerOverlay = NULL;
    SDL_Surface* rotationInclinometerJeepFront = NULL;
    SDL_Surface* rotationInclinometerJeepSide = NULL;
    SDL_Rect inclinometerJeepOverlayPosition;
    SDL_Rect inclinometerJeepFrontPosition;
    SDL_Rect inclinometerJeepSidePosition;

    SDL_VideoInfo* videoInfo;

    void INThandler(int sig)
    {
    SDL_FreeSurface(screen);
    SDL_Quit();
    signal(sig, SIG_IGN);
    exit(0);
    }

    int mymillis()
    {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (tv.tv_sec) * 1000 + (tv.tv_usec)/1000;
    }

    int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)
    {
    long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) – (t1->tv_usec + 1000000 * t1->tv_sec);
    result->tv_sec = diff / 1000000;
    result->tv_usec = diff % 1000000;
    return (diff<0);
    }

    int main(int argc, char *argv[])
    {

    float rate_gyr_y = 0.0; // [deg/s]
    float rate_gyr_x = 0.0; // [deg/s]
    float rate_gyr_z = 0.0; // [deg/s]

    int acc_raw[3];
    int mag_raw[3];
    int gyr_raw[3];

    float gyroXangle = 0.0;
    float gyroYangle = 0.0;
    float gyroZangle = 0.0;
    float AccYangle = 0.0;
    float AccXangle = 0.0;
    float CFangleX = 0.0;
    float CFangleY = 0.0;

    int startInt = mymillis();
    struct timeval tvBegin, tvEnd,tvDiff;

    signed int acc_y = 0;
    signed int acc_x = 0;
    signed int acc_z = 0;
    signed int gyr_x = 0;
    signed int gyr_y = 0;
    signed int gyr_z = 0;

    signal(SIGINT, INThandler);

    enableIMU();

    gettimeofday(&tvBegin, NULL);

    if(argc <=1)
    startSDL();
    else if (strcmp(argv[1],”nosdl”)!= 0)
    startSDL();

    while(1)
    {
    startInt = mymillis();

    //read ACC and GYR data
    readACC(acc_raw);
    readGYR(gyr_raw);

    //Convert Gyro raw to degrees per second
    rate_gyr_x = (float) gyr_raw[0] * G_GAIN;
    rate_gyr_y = (float) gyr_raw[1] * G_GAIN;
    rate_gyr_z = (float) gyr_raw[2] * G_GAIN;

    //Calculate the angles from the gyro
    gyroXangle+=rate_gyr_x*DT;
    gyroYangle+=rate_gyr_y*DT;
    gyroZangle+=rate_gyr_z*DT;

    //Convert Accelerometer values to degrees
    AccXangle = (float) (atan2(acc_raw[1],acc_raw[2])+M_PI)*RAD_TO_DEG;
    AccYangle = (float) (atan2(acc_raw[2],acc_raw[0])+M_PI)*RAD_TO_DEG;

    //Change the rotation value of the accelerometer to -/+ 180 and move the Y axis ‘0’ point to up.
    //Two different pieces of code are used depending on how your IMU is mounted.
    //If IMU is upside down
    /*
    if (AccXangle >180)
    AccXangle -= (float)360.0;

    AccYangle-=90;
    if (AccYangle >180)
    AccYangle -= (float)360.0;
    */

    //If IMU is up the correct way, use these lines
    AccXangle -= (float)180.0;
    if (AccYangle > 90)
    AccYangle -= (float)270;
    else
    AccYangle += (float)90;

    //Kalman Filter
    float kalmanX = kalmanFilterX(AccXangle, rate_gyr_x);
    float kalmanY = kalmanFilterY(AccYangle, rate_gyr_y);
    printf (“33[22;31mkalmanX %7.3f 33[22;36mkalmanY %7.3f\t\e[m”,kalmanX,kalmanY);

    //Complementary filter used to combine the accelerometer and gyro values.
    CFangleX=AA*(CFangleX+rate_gyr_x*DT) +(1 – AA) * AccXangle;
    CFangleY=AA*(CFangleY+rate_gyr_y*DT) +(1 – AA) * AccYangle;

    printf (” GyroX %7.3f \t AccXangle \e[m %7.3f \t 33[22;31mCFangleX %7.3f33[0m\t GyroY %7.3f \t AccYangle %7.3f \t 33[22;36mCFangleY %7.3f\t33[0m\n”,gyroXangle,AccXangle,CFangleX,gyroYangle,AccYangle,CFangleY);

    if(argc <=1)
    graphics(kalmanX,kalmanY);
    else if (strcmp(argv[1],”nosdl”)!= 0)
    graphics(kalmanX,kalmanY);

    //Each loop should be at least 20ms.
    while(mymillis() – startInt < (DT*1000))
    {
    usleep(100);
    }

    printf(“Loop Time %d\t”, mymillis()- startInt);
    }
    }

    int startSDL()
    {
    //fb1 = small TFT. fb0 = HDMI/RCA output
    putenv(“SDL_FBDEV=/dev/fb0”);

    //Initialize SDL and disable mouse
    SDL_Init(SDL_INIT_VIDEO);
    SDL_ShowCursor(SDL_DISABLE);

    //Get information about the current video device. E.g. resolution and bits per pixal
    videoInfo = SDL_GetVideoInfo ();

    //Setup a Video mode.
    screen = SDL_SetVideoMode(videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel, SDL_SWSURFACE );
    if ( screen == NULL ) {
    fprintf(stderr, “Unable to setvideo: %s\n”, SDL_GetError());
    exit(1);
    }

    //Load image.
    inclinometerJeepFront = IMG_Load(“inclinometerJeepFront.png”);
    if (inclinometerJeepFront == NULL){
    printf(“error loading JeepFront image\n”);
    SDL_Quit();
    exit(1);
    }
    //Convert the image to a format we can use.
    compatibleInclinometerJeepFront = SDL_DisplayFormatAlpha(inclinometerJeepFront);

    //Load image.
    inclinometerJeepSide = IMG_Load(“inclinometerJeepSide.png”);
    if (inclinometerJeepSide == NULL){
    printf(“error loading JeepSide image\n”);
    SDL_Quit();
    exit(1);
    }
    //Convert the image to a format we can use.
    compatibleInclinometerJeepSide = SDL_DisplayFormatAlpha(inclinometerJeepSide);

    //Load image.
    inclinometerOverlay = IMG_Load(“inclinometerOverlay.png”);
    if (inclinometerOverlay == NULL){
    printf(“error loading Overlay image\n”);
    SDL_Quit();
    exit(1);
    }
    //Convert the image to a format we can use.
    compatibleInclinometerOverlay = SDL_DisplayFormatAlpha(inclinometerOverlay);

    //Position the overlay in the middle of the screen. screen heigth minus the height of the overlay image.
    inclinometerJeepOverlayPosition.y = (videoInfo->current_h/2)-(compatibleInclinometerOverlay->h/2);

    }

    int graphics(float carRoll, float carPitch)
    {

    //Set all pixals to black to clear the last image.
    SDL_FillRect(screen,NULL,0x000000);

    //Position of both jeep images.
    inclinometerJeepFrontPosition.x = 30;
    inclinometerJeepFrontPosition.y = (videoInfo->current_h/2)-(compatibleInclinometerJeepFront->h/2);
    inclinometerJeepSidePosition.x = 262;
    inclinometerJeepSidePosition.y = (videoInfo->current_h/2)-(compatibleInclinometerJeepFront->h/2);

    //Rotate the images based on pitch and roll.
    rotationInclinometerJeepSide = rotozoomSurface(compatibleInclinometerJeepSide, carPitch, 1.0, 0.0);
    rotationInclinometerJeepFront = rotozoomSurface(compatibleInclinometerJeepFront, carRoll, 1.0, 0.0);

    //Recenter pivot point.
    inclinometerJeepFrontPosition.x -= rotationInclinometerJeepFront->w/2-compatibleInclinometerJeepFront->w/2;
    inclinometerJeepFrontPosition.y -= rotationInclinometerJeepFront->h/2-compatibleInclinometerJeepFront->h/2;
    inclinometerJeepSidePosition.x -= rotationInclinometerJeepSide->w/2-compatibleInclinometerJeepSide->w/2;
    inclinometerJeepSidePosition.y -= rotationInclinometerJeepSide->h/2-compatibleInclinometerJeepSide->h/2;

    //Blit the three iamges to the surface.
    SDL_BlitSurface( compatibleInclinometerOverlay, NULL, screen, &inclinometerJeepOverlayPosition);
    SDL_BlitSurface( rotationInclinometerJeepFront, NULL, screen, &inclinometerJeepFrontPosition);
    SDL_BlitSurface( rotationInclinometerJeepSide, NULL, screen, &inclinometerJeepSidePosition);

    //Send the surface to the display.
    SDL_Flip(screen);

    //Free surfaces.
    SDL_FreeSurface(screen);
    SDL_FreeSurface(rotationInclinometerJeepFront);
    SDL_FreeSurface(rotationInclinometerJeepSide);
    return 0;

    }

    float kalmanFilterX(float accAngle, float gyroRate)
    {
    float y, S;
    float K_0, K_1;

    KFangleX += DT * (gyroRate – x_bias);

    XP_00 += – DT * (XP_10 + XP_01) + Q_angle * DT;
    XP_01 += – DT * XP_11;
    XP_10 += – DT * XP_11;
    XP_11 += + Q_gyro * DT;

    y = accAngle – KFangleX;
    S = XP_00 + R_angle;
    K_0 = XP_00 / S;
    K_1 = XP_10 / S;

    KFangleX += K_0 * y;
    x_bias += K_1 * y;
    XP_00 -= K_0 * XP_00;
    XP_01 -= K_0 * XP_01;
    XP_10 -= K_1 * XP_00;
    XP_11 -= K_1 * XP_01;

    return KFangleX;
    }

    float kalmanFilterY(float accAngle, float gyroRate)
    {
    float y, S;
    float K_0, K_1;

    KFangleY += DT * (gyroRate – y_bias);

    YP_00 += – DT * (YP_10 + YP_01) + Q_angle * DT;
    YP_01 += – DT * YP_11;
    YP_10 += – DT * YP_11;
    YP_11 += + Q_gyro * DT;

    y = accAngle – KFangleY;
    S = YP_00 + R_angle;
    K_0 = YP_00 / S;
    K_1 = YP_10 / S;

    KFangleY += K_0 * y;
    y_bias += K_1 * y;
    YP_00 -= K_0 * YP_00;
    YP_01 -= K_0 * YP_01;
    YP_10 -= K_1 * YP_00;
    YP_11 -= K_1 * YP_01;

    return KFangleY;
    }

    #3992
    jawood
    Participant

    Ow yeah that’s better very stable now and accurate. Cant believe the difference just using the kalman filter makes.

    Now all I need to know is how to make it run as a full screen app without taskbar

    #3994
    Mark Williams
    Keymaster

    you are right… in theory, it shouldn’t be too hard. The code looks correct

    Mark --OzzMaker.com --

    #3995
    jawood
    Participant

    Yeah it works great now with the Kalman Filter applied.
    I would like to be able to get it to run without the blue bar at the top of the window and how to get it to open full screen. Any help with that would be much appreciated. Thanks

    #3996
    jawood
    Participant

    Ow one more thing I just did the screen blanking thing and its still blanking.

    sudo apt-get install x11-xserver-utils
    sudo nano /etc/xdg/lxsession/LXDE/autostart

    added

    @xset s off # don’t activate screensaver
    @xset -dpms # disable DPMS (Energy Star) features.
    @xset s noblank # don’t blank the video device

    Reboot. Screen still blanking after 10mins

    #3997
    jawood
    Participant

    Im assuming I add

    SDL_WM_ToggleFullScreen(SDL_Surface *surface);

    I added it to function:-

    //Initialise SDL and Disable Mouse
    SDL_Init(SDL_INIT_VIDEO);
    SDL_ShowCursor(SDL_DIABLE);
    SDL_WM_ToggleFullScreen(SDL_Surface *surface);

    Compile:-

    gcc -o KalmanFilterLevelMeter1 -lm LevelMeterKalmanFiltered.c sdl-config --cflags sdl-config --libs -lSDL_image -lSDL_gfx

    And get error:-

    LevelMeterKalmanFiltered.c: In function ‘startSDL’:
    LevelMeterKalmanFiltered.c:233:26: error: expected expression before ‘SDL_Surface’
    LevelMeterKalmanFiltered.c:236:19: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
    LevelMeterKalmanFiltered.c: In function ‘graphics’:
    LevelMeterKalmanFiltered.c:299:38: warning: assignment makes pointer from integer without a cast [enabled by default]
    LevelMeterKalmanFiltered.c:300:39: warning: assignment makes pointer from integer without a cast [enabled by default]

    #4001
    Mark Williams
    Keymaster

    Regarding Blanking, I needed to update that page… there has been a resent change that breaks the use of xset directly in the autostart.
    The page now has;
    Disable X blanking
    1. Install X server utilities, they will most likely already be installed.
    sudo apt-get install x11-xserver-utils
    2. Create a small script which is used to change the screen saver settings.
    sudo nano /etc/X11/Xsession.d/disableblank.sh
    3. Add these three lines.

    xset s off      # don't activate screensaver
    xset -dpms      # disable DPMS (Energy Star) features.
    xset s noblank  # don't blank the video device

    4. Change the permissions on the file.
    sudo chmod +x /etc/X11/Xsession.d/disableblank.sh
    5. Force the file to run when X starts
    sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
    Or /etc/xdg/lxsession/LXDE/autostart on older version of Raspbian

     

    And add this line to the bottom;

    /etc/X11/Xsession.d/disableblank.sh

    Mark --OzzMaker.com --

Viewing 15 posts - 16 through 30 (of 36 total)
  • You must be logged in to reply to this topic.

Blip, blop, bloop…