
Recevoir une donnée
Revision 0:f82efb692e3b, committed 2018-06-14
- Comitter:
- MoussOudj
- Date:
- Thu Jun 14 07:04:14 2018 +0000
- Commit message:
- Recevoir une seule donn?e
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9685.cpp Thu Jun 14 07:04:14 2018 +0000 @@ -0,0 +1,167 @@ +#ifndef PCA9685_LIBRARY_CPP +#define PCA9685_LIBRARY_CPP + + +#include "mbed.h" +#include "PCA9685.h" +#include "definitions.h" + + +PCA9685::PCA9685(uint8_t i2c_address, I2C i2c_object, float frequency) : + + i2c_addr(i2c_address), + freq(frequency), + i2c(i2c_object) + +{ + +} + +void PCA9685::init(void) +{ + + reset(); + + uint8_t prescale = (uint8_t) (OSC_CLOCK / (4096 * PWM_SCALER * freq)) - 1; + + write_8(MODE1, 0x21); //0010 0001 : AI ENABLED + write_8(MODE2, 0x07); //0000 0111 : NOT INVRT, CHANGE ON STOP, TOTEM POLE, \OE = 1, LEDn = HIGH IMP + + set_prescale(prescale); + +} + +void PCA9685::reset(void) +{ + + write_8(MODE1,0x00); + +} + +void PCA9685::set_prescale(uint8_t prescale) +{ + + uint8_t oldmode = read_8(MODE1); + uint8_t newmode = (oldmode&0x7F) | 0x10; // set the sleep bit + + write_8(MODE1, newmode); // send the device to sleep + wait_ms(5); + write_8(PRESCALE, prescale); // set the prescaler + write_8(MODE1, oldmode); + wait_ms(5); + write_8(MODE1, oldmode | 0xa1); // wake up the device + +} + + +//NB REQUIRES AUTO-INCREMENT MODE ENABLED +//0 <= pwm_output <= 15 +//0 <= (count_on || count_off) <= 4095 +void PCA9685::set_pwm_output(int pwm_output, uint16_t count_on, uint16_t count_off) +{ + + char msg[5]; + + msg[0] = LED0_ON_L + (4 * pwm_output); + msg[1] = count_on; + msg[2] = count_on >> 8; + msg[3] = count_off; + msg[4] = count_off >> 8; + + i2c.write(i2c_addr, msg, 5); + +} + +void PCA9685::set_pwm_output_on_0(int pwm_output, uint16_t count_off) +{ + + char msg[3]; + + msg[0] = LED0_ON_L + 2 + (4 * pwm_output); + msg[1] = count_off; + msg[2] = count_off >> 8; + + i2c.write(i2c_addr,msg,3); + +} + + +//NB REQUIRES AUTO-INCREMENT MODE ENABLED +//0 <= pwm_output <= 15 +void PCA9685::set_pwm_duty(int pwm_output, float duty_cycle) +{ + + if (duty_cycle > 1.0) { + duty_cycle = 1.0; + } + if (duty_cycle < 0.0) { + duty_cycle = 0.0; + } + + uint16_t count_off = (uint16_t) (duty_cycle * 4095); + uint16_t count_on = 0x0000; + + set_pwm_output(pwm_output, count_on, count_off); + +} + + +//NB REQUIRES AUTO-INCREMENT MODE ENABLED +//0 <= pwm_output <= 15 +void PCA9685::set_pwm_pw(int pwm_output, float pulse_width_us) +{ + + float period_us = (1e6/freq); + + float duty = pulse_width_us/period_us; + + set_pwm_duty(pwm_output, duty); + +} + + +void PCA9685::update(void) +{ + + i2c.stop(); + +} + + + +void PCA9685::write_8(uint8_t reg, uint8_t msg) +{ + + char send[2]; //Store the address and data in an array + send[0] = reg; + send[1] = msg; + i2c.write(i2c_addr, send, 2); + +} + +uint8_t PCA9685::read_8(uint8_t reg) +{ + + char send[1] ; + send[0] = reg; + i2c.write(i2c_addr, send, 1); + char recieve[1]; + i2c.read(i2c_addr, recieve, 1); + return recieve[0]; + +} + +int PCA9685::convert_pwm_value(float pulse_width_us, float period_us) +{ + + int result; + float interim; + + interim = ((pulse_width_us / period_us) * 4095); //scale the pulse width to a 12-bit scale + result = (int) interim; //round the value to the nearest integer + + return result; + +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9685.h Thu Jun 14 07:04:14 2018 +0000 @@ -0,0 +1,32 @@ +#ifndef PCA9685_LIBRARY_H +#define PCA9685_LIBRARY_H + +#include "mbed.h" +#include "definitions.h" + + +class PCA9685 { + + public: + PCA9685(uint8_t i2c_addr, I2C i2c_object, float frequency); + void init(void); + void set_pwm_output(int pwm_output, uint16_t count_on, uint16_t count_off); + void set_pwm_output_on_0(int pwm_output, uint16_t count_off); + void set_pwm_duty(int pwm_output, float duty_cycle); + void set_pwm_pw(int pwm_output, float pulse_width_us); + void update(void); + + private: + void reset(void); + void write_8(uint8_t reg, uint8_t msg); + uint8_t read_8(uint8_t reg); + void set_prescale(uint8_t prescale); + int convert_pwm_value(float pulse_width_us, float period_us); + + private: + int i2c_addr; + float freq; + I2C i2c; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/definitions.h Thu Jun 14 07:04:14 2018 +0000 @@ -0,0 +1,24 @@ +#ifndef PCA9685_LIBRARY_DEFINITIONS_H +#define PCA9685_LIBRARY_DEFINITIONS_H + +#define ADDR 0x80 + +#define MODE1 0x0 +#define MODE2 0x1 +#define PRESCALE 0xFE + +#define LED0_ON_L 0x6 +#define LED0_ON_H 0x7 +#define LED0_OFF_L 0x8 +#define LED0_OFF_H 0x9 + +#define ALLLED_ON_L 0xFA +#define ALLLED_ON_H 0xFB +#define ALLLED_OFF_L 0xFC +#define ALLLED_OFF_H 0xFD + +#define OSC_CLOCK 25e6 + +#define PWM_SCALER 0.90425 //set by manual calibration - ratio of FREQUENCY_SET:ACTUAL_OUTPUT + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Jun 14 07:04:14 2018 +0000 @@ -0,0 +1,148 @@ +#include "mbed.h" +#include "PCA9685.h" + + +Serial xbee(PA_9, PA_10); +DigitalOut myled(LED1); +Serial pc(USBTX,USBRX); +I2C i2c_PCA(PB_9, PB_8); // Utilisation et déclaration d'un port I2C pour communiquer avec la carte PWM Adafruit +PCA9685 PCA_SERVO(ADDR, i2c_PCA, 50); + +uint8_t text_xbee[21]; +uint8_t idx_carac_xbee_in = 0; +uint8_t send_measure = 0; + + +/* +void irq_xbee(void){ // Fonction d'interruption qui agit dès qu'une mesure est arrivée + text_xbee[idx_carac_xbee_in] = xbee.getc(); + send_measure = 1; // Une mesure est reçu, on met donc le flag à 1 + idx_carac_xbee_in = (idx_carac_xbee_in+1) % 5; + +}*/ + + +//Phalanges doigt 0 // Définitions de chaque servomoteur sur chaque doigt. Le doigt 0 correspond à l'index, et les servos se suivent de haut en bas. M0 est donc le servo de la base du doigt, et M3 le servomoteur le plus haut +#define D0M1 0x00 // On attribue à chaque servomoteur une adresse sur laquelle on enverra l'ordre d'angle +#define D0M2 0x01 // Ces adresses correspondent à des ports de la carte PWM Adafruit +#define D0M3 0x02 +#define D0M0 0x03 + +//Phalanges doigt 1 // Définitions de chaque servomoteur du doigt majeur +#define D1M1 0x04 +#define D1M2 0x05 +#define D1M3 0x06 +#define D1M0 0x07 + +//Phalanges doigt 2 // Définitions de chaque servcomoteur de l'annulaire +#define D2M1 0x08 +#define D2M2 0x09 +#define D2M3 0x0A +#define D2M0 0x0B + +//Phalanges doigt 3 // Définitions de chaque servomoteur de l'auriculaire +#define D3M1 0x0C +#define D3M2 0x0D +#define D3M3 0x0E +#define D3M0 0x0F + +int i = 0; + + + +void angle(int moteur, int valeur){ // Fonction qui envoie les données au servomoteur correspondant + + valeur = valeur * 10;// Mise en forme correspondant + valeur = valeur + 1100;// Ajout de l'offset + + if(valeur >= 2400) // On borne les données reçues + { + valeur = 2400; + } + if(valeur <= 1100) + { + valeur = 1100; + } + + PCA_SERVO.set_pwm_pw(moteur, valeur); // Puis on envoie au moteur +} + + + + + + + + + + +int main() { + + int i = 0; + + pc.baud(115200); + xbee.baud(9600); + //xbee.attach(&irq_xbee); + + + + + PCA_SERVO.init(); //Initialisation des servomoteurs + for(i=0;i<=15;i++){ // On met tous les servomoteurs dans une position qui équivaut à la position de repos + PCA_SERVO.set_pwm_output_on_0(i, 0); + } + + + + /*angle(D1M1, ); // Les valeurs sont différentes les unes des autres car les servomoteurs ne sont pas tous identiques et ils prennent de la place, ils se décalent donc un peu + angle(D1M2, 35); + angle(D1M3, 35);*/ + + /* for(i;i<10;i++){ + + angle(4,80); + + wait(2); + + angle(4,20); + }*/ + + int test; + + /* + for(i = 0 ;i<10;i++){ + + angle(4,120); + + wait_ms(100); + + angle(4,30); + }*/ + + while(1) { + + + + + + + test = xbee.getc(); + //pc.printf("%d \r\n",test); + + + + /*angle(D1M1, text_xbee[1]); + angle(D1M2, text_xbee[1]); + angle(D1M3, text_xbee[1]);*/ + + angle(4, test); + /*angle(D1M2, test); + angle(D1M3, test);*/ + + /*PCA_SERVO.set_pwm_duty(4, 0.5); + + wait_ms(20); + + PCA_SERVO.set_pwm_duty(4, 0.1);*/ + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Jun 14 07:04:14 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/5aab5a7997ee \ No newline at end of file