K9 Head controlled uses CAN communications, drives ear servos, gun servo and eyes.

Dependencies:   MultiChannelRelay Adafruit_PWMServoDriver

main.cpp

Committer:
SomeRandomBloke
Date:
2020-09-08
Revision:
0:d19dd72afbb0
Child:
1:558786a5d3f9

File content as of revision 0:d19dd72afbb0:

/** K9 Dr Who Robot dog, Head controler.
* Based on NucleoF303k8 CAN Receive node
 *
 *
 *
 *
 *
 */

#include "mbed.h"
#include "MultiChannelRelay.h"
//#include "PCA9685.h"
#include "Adafruit_PWMServoDriver.h"

//     "requires": ["bare-metal"],

#define NODE_ID 0x456
#define NODE_RELAY 0x81
#define NODE_MOTOR 0x82
#define NODE_SERVO 0x83


#define WAVE_MIN  120
#define WAVE_MAX  450
#define WAVE_FWD  285
#define RIGHT_EAR 0
#define LEFT_EAR  1
#define GUN_SERVO 2
#define EYE_LEDS  3

// Blinking rate in milliseconds
#define BLINKING_RATE     500

I2C i2c(I2C_SDA, I2C_SCL);

//PCA9685 pwmServo( I2C_SDA, I2C_SCL, PCA9685::PCA9685_ADDRESS_0, 400000 );
Adafruit_PWMServoDriver pwmServo( &i2c );

void canRcv(void);
char RcvData[8];
DigitalOut led(PB_3);
//Serial pc(PA_2,PA_3,115200);
CAN can(PA_11, PA_12,500000);       // Rx, Tx
CANMessage msg(0x456,CANStandard);

//I2C i2c(I2C_SDA, I2C_SCL);

MultiChannelRelay relay(&i2c);


/** CAN **/
void canRcv(void)
{
    led =!led;
    can.read(msg);
//    printf("\033[1;1HCAN TRANSID: 0x%x", msg.id);
//    if(msg.id == NODE_ID) {
    for(uint8_t i=0; i<8; i++) {
        RcvData[i] = msg.data[i];
    }
    /*    printf("\033[2;1HCAN DATA[0]: 0x%x ", RcvData[0]);
        printf("\033[3;1HCAN DATA[1]: 0x%x ", RcvData[1]);
        printf("\033[4;1HCAN DATA[2]: 0x%x ", RcvData[2]);
        printf("\033[5;1HCAN DATA[3]: 0x%x ", RcvData[3]);
        printf("\033[6;1HCAN DATA[4]: 0x%x ", RcvData[4]);
        printf("\033[7;1HCAN DATA[5]: 0x%x ", RcvData[5]);
        printf("\033[8;1HCAN DATA[6]: 0x%x ", RcvData[6]);
        printf("\033[9;1HCAN DATA[7]: 0x%x ", RcvData[7]);
        printf("\033[10;1HCAN LEN:    %d  ",msg.len);
        printf("\033[11;1HCAN FORMAT: %d  ",msg.format);
        printf("\033[12;1HCAN TYPE:   %d  ",msg.type);
        printf("\033[13;1HCAN RDErr:  %d  ",can.rderror());
    */
    /*
        // Byte 0 is node type
        switch( RcvData[0] ) {
            case NODE_RELAY:
                // Byte 1 is relay bit pattern
                relay.channelCtrl( RcvData[1] & 0x0F );
                printf("Relay %d  \r\n", RcvData[1] & 0x0F );
                break;
            case NODE_MOTOR:
                // Bytes 1/2 L/H signed int Right direction/speed
                // Bytes 3/4 L/H signed int Left direction/speed
                break;
            case NODE_SERVO:
                // Byte 1 servo number
                // Byte 2/3 L/H value
                break;
        }
    */
//    }
}


int main()
{
    // Setup hardware

    //PCA9685::PCA9685_status_t  status = pwmServo.PCA9685_SoftReset();
    pwmServo.begin();

    // Configure the PWM frequency and wake up the device
    //status = pwmServo.PCA9685_SetPWM_Freq( 1000 );   // PWM frequency: 1kHz
    //status = pwmServo.PCA9685_SetMode( PCA9685::MODE1_SLEEP_DISABLED );
    pwmServo.setPWMFreq(50);  // 50Hz

#ifdef NOTUSED
    printf("\033[2J\033[1;1HTest Relays\n");

    // Relay test
    relay.channelCtrl(0x00);
    thread_sleep_for(100);
    relay.channelCtrl(0x01);
    thread_sleep_for(100);
    relay.channelCtrl(0x02);
    thread_sleep_for(100);
    relay.channelCtrl(0x04);
    thread_sleep_for(100);
    relay.channelCtrl(0x08);
    thread_sleep_for(100);
    relay.channelCtrl(0x00);

    // Servo test
    printf("\033[2J\033[1;1HTest PWM\n");
    for(int i=WAVE_MIN; i<WAVE_MAX; ) {
        //status = myPWMSensor.PCA9685_SetPWM_DutyCycle( PCA9685::PCA9685_LED1, 10, 30 );
        pwmServo.setPWM(RIGHT_EAR, 0, i);
        thread_sleep_for(20);
        i += 10;
    }
    for(int i=WAVE_MAX; i>WAVE_MIN; ) {
        //status = myPWMSensor.PCA9685_SetPWM_DutyCycle( PCA9685::PCA9685_LED1, 10, 30 );
        pwmServo.setPWM(RIGHT_EAR, 0, i);
        thread_sleep_for(20);
        i -= 10;
    }
    for( int i=1; i<5; i++ ) {
        pwmServo.setPWM(RIGHT_EAR, 0, WAVE_MIN);
        pwmServo.setPWM(LEFT_EAR, 0, WAVE_MAX);
        thread_sleep_for(700);
        pwmServo.setPWM(RIGHT_EAR, 0, WAVE_MAX);
        pwmServo.setPWM(LEFT_EAR, 0, WAVE_MIN);
        thread_sleep_for(700);
    }

    for( int n=0; n<10; n++) {
        pwmServo.setPWM(EYE_LEDS, 0, 0xFFF);
        thread_sleep_for(500);
        pwmServo.setPWM(EYE_LEDS, 0, 0);
        thread_sleep_for(500);
        /*
                for(int i=0; i<0xFFFF; ) {
                    //status = myPWMSensor.PCA9685_SetPWM_DutyCycle( PCA9685::PCA9685_LED1, 10, 30 );
                    pwmServo.setPWM(EYE_LEDS, 0, i);
                    thread_sleep_for(10);
                    i += 10;
                }
                for(int i=0xFFFF; i>0; ) {
                    //status = myPWMSensor.PCA9685_SetPWM_DutyCycle( PCA9685::PCA9685_LED1, 10, 30 );
                    pwmServo.setPWM(EYE_LEDS, 0, i);
                    thread_sleep_for(10);
                    i -= 10;
                }
         */
    }

#endif

    relay.channelCtrl(0x00);
    pwmServo.setPWM(RIGHT_EAR, 0, WAVE_FWD);
    pwmServo.setPWM(LEFT_EAR, 0, WAVE_FWD);

    pwmServo.setPWM(EYE_LEDS, 0, 0);

    printf("\033[2J\033[1;1HSTART mbed 6.2\n");

    // Initialise the digital pin LED1 as an output
    DigitalOut led(LED1);

//    while (true) {
//        led = !led;
//        thread_sleep_for(500);
//    }

    can.mode( CAN::Normal );
//    can.attach(callback( &canRcv ),CAN::RxIrq);

    while(1) {
        led = !led;
        if( can.read(msg) > 0 ) {
//    printf("\033[1;1HCAN TRANSID: 0x%x", msg.id);
//    if(msg.id == NODE_ID) {
            for(uint8_t i=0; i<8; i++) {
                RcvData[i] = msg.data[i];
            }

            printf("\033[2;1HCAN DATA[0]: 0x%x", RcvData[0]);
            printf("\033[3;1HCAN DATA[1]: 0x%x", RcvData[1]);
            printf("\033[4;1HCAN DATA[2]: 0x%x", RcvData[2]);
            printf("\033[5;1HCAN DATA[3]: 0x%x", RcvData[3]);
            printf("\033[6;1HCAN DATA[4]: 0x%x", RcvData[4]);
            printf("\033[7;1HCAN DATA[5]: 0x%x", RcvData[5]);
            printf("\033[8;1HCAN DATA[6]: 0x%x", RcvData[6]);
            printf("\033[9;1HCAN DATA[7]: 0x%x", RcvData[7]);

            // Byte 0 is node type
            switch( RcvData[0] ) {
                case NODE_RELAY:
                    // Byte 1 is relay bit pattern
                    relay.channelCtrl( RcvData[1] & 0x0F );
                    //printf("Relay %d  \r\n", RcvData[1] & 0x0F );
                    break;
                case NODE_MOTOR:
                    // Bytes 1/2 L/H signed int Right direction/speed
                    // Bytes 3/4 L/H signed int Left direction/speed
                    break;
                case NODE_SERVO:
                    // Byte 1 servo number
                    // Byte 2/3 L/H value
                    uint16_t servoVal = (RcvData[3] << 8) | RcvData[2];
                    pwmServo.setPWM(RcvData[1] & 0x0F, 0, servoVal );
                    break;

//                default:    // Reset data
//                    RcvData[0] = 0;
//                    break;

            }
            RcvData[0] = 0;
        }
        thread_sleep_for(100);
    }

}