Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arduino I2C从-主通信问题_Arduino_Communication_I2c_Master_Slave - Fatal编程技术网

Arduino I2C从-主通信问题

Arduino I2C从-主通信问题,arduino,communication,i2c,master,slave,Arduino,Communication,I2c,Master,Slave,我在使用I2C通信时,从Arduino Uno(从)读取Arduino Mega(主)中的随机数据时遇到问题。 一些背景:我正在从Uno读取编码器数据,并通过I2C通信发送到Mega。MEga中使用编码器数据来调整电机的速度,以便不同车轮的每秒转数具有相同的值 当我包含IF条件或函数时,读取随机数据的问题就会出现。 即使包含的if条件是空的,或者对函数的调用是空的,它也会开始从Uno读取随机错误的数据。 如果我没有代码的调整部分(如果条件/功能),那么从Uno读取数据就可以了 如果有人能帮忙,我

我在使用I2C通信时,从Arduino Uno(从)读取Arduino Mega(主)中的随机数据时遇到问题。 一些背景:我正在从Uno读取编码器数据,并通过I2C通信发送到Mega。MEga中使用编码器数据来调整电机的速度,以便不同车轮的每秒转数具有相同的值

当我包含IF条件或函数时,读取随机数据的问题就会出现。 即使包含的if条件是空的,或者对函数的调用是空的,它也会开始从Uno读取随机错误的数据。 如果我没有代码的调整部分(如果条件/功能),那么从Uno读取数据就可以了

如果有人能帮忙,我们将不胜感激

主代码:

#include <SoftwareSerial.h>
#include <SabertoothSimplified.h>
// Include the required Wire library for I2C<br>#include
#include <Wire.h>

// RX on pin 17 (to S2), TX on pin 16 (to S1).
SoftwareSerial SWSerial(NOT_A_PIN, 16);
// Use SWSerial as the serial port.
SabertoothSimplified ST(SWSerial);

//////////////////ENCODER DATA//////////////////
unsigned int revolutions_L_rpm = 0;
unsigned int revolutions_R_rpm = 0;

int16_t x = 0;
int16_t y = 0;
////////////////////////////////////////////////

//////////////VARIABLES FOR ADJUST//////////////
int error = 0;
int kp = 12;
int adjusted = 0;
////////////////////////////////////////////////

////////////////////MOTORS//////////////////////
//Declare the arduino pins
int LEDg = 7;
int LEDr = 6;
int LEDy = 5;
int speedVar = 0;
int speedOne = 0;
int speedTwo = 0;
int power;
////////////////////END/////////////////////////

void setup() {
  //initlize the mode of the pins
  pinMode(LEDg,OUTPUT);
  pinMode(LEDr,OUTPUT);
  pinMode(LEDy,OUTPUT);
  //set the serial communication rate
  Serial.begin(9600);
  SWSerial.begin(9600);
  Wire.begin();
}

void loop()
{
  //check whether arduino is reciving signal or not
  if(Serial.available() > 0){
    char val = Serial.read();//reads the signal
    Serial.print("Recieved: ");
    Serial.println(val);

    switch(val){
      /*********Increase speed by 1 as long as e(triangle) is held*********/
      case 'a':
        forward();
        break;

      /*********Decrease speed by 1 as long as g(x) is held*********/
      case 'c':
        reverse();
        break;

      /*********Increase speed by 1 as long as e(triangle) is held*********/
      case 'd':
        turnLeft();
        break;

      /*********Decrease speed by 1 as long as g(x) is held*********/
      case 'b':
        turnRight();
        break;

      /*********Toggle when Circle is held for 5 seconds*********/
      case 'f':
        toggleSwitch(LEDy);
        break;

      /*********Toggle when Square is held for 5 seconds*********/
      case 'h':
        stopMotors();
        break;
    }

    Serial.print("sppedVar = ");
    Serial.print(speedVar);
    Serial.print("\tleftSpeed: ");
    Serial.print(speedOne);
    Serial.print("\trightSpeed: ");
    Serial.println(speedTwo);
  }

  Wire.requestFrom(9,4); // Request 4 bytes from slave arduino (9)
  byte a = Wire.read();
  Serial.print("a: ");
  Serial.print(a);
  byte b = Wire.read();
  Serial.print("  b: ");
  Serial.print(b);
  byte e = Wire.read();
  Serial.print(" --- e: ");
  Serial.print(e);
  byte f = Wire.read();
  Serial.print("  f: ");
  Serial.print(f);
  x = a;
  x = (x << 8) | b;
  Serial.print("\tX: ");
  Serial.print(x);
  y = e;
  y = (y << 8) | f;
  Serial.print("\tY: ");
  Serial.print(y);
  revolutions_L_rpm = x;
  revolutions_R_rpm = y;

  if ((revolutions_L_rpm != revolutions_R_rpm) && (speedVar != 0)){
    error = 0;
    error = revolutions_L_rpm - revolutions_R_rpm;
    adjusted = error/kp;
    Serial.print("Error: ");
    Serial.print(error);
    Serial.print("Error/kp: ");
    Serial.println(adjusted);

    if ((speedTwo < 20) && (speedTwo > -20)){
      speedTwo -= adjusted;
      power = speedTwo;
      ST.motor(2, -power);
      //delay(20);
    }
  }

  // Print out rpm
  Serial.print("Left motor rps*100: ");
  Serial.print(revolutions_L_rpm);
  Serial.print(" ///// Right motor rps*100: ");
  Serial.println(revolutions_R_rpm);

    // Print out speed
  Serial.print("speedOne: ");
  Serial.print(speedOne);
  Serial.print("\tspeedTwo: ");
  Serial.println(speedTwo);

  delay(1000);
}
// Include the required Wire library for I2C<br>#include <Wire.h>
#include <Wire.h>

// Checked for main program
volatile boolean counterReady;

// Internal to counting routine
unsigned int timerPeriod;
unsigned int timerTicks;
unsigned long overflowCount;


// The pin the encoder is connected
int encoder_in_L = 2;
int encoder_in_R = 3;

// The number of pulses per revolution
// depends on your index disc!!
unsigned int pulsesperturn = 16;

// The total number of revolutions
int16_t revolutions_L = 0;
int16_t revolutions_R = 0;

int16_t revolutions_L_rpm = 0;
int16_t revolutions_R_rpm = 0;

// Initialize the counter
int16_t pulses_L = 0;
int16_t pulses_R = 0;

byte myData[4];

// This function is called by the interrupt
void count_L() {
  pulses_L++;
}
void count_R() {
  pulses_R++;
}

void startCounting(unsigned int ms) {
  counterReady = false;     // time not up yet
  timerPeriod = ms;         // how many ms to count to
  timerTicks = 0;         // reset interrupt counter
  overflowCount = 0;      // no overflows yet

  // Reset timer 2
  TCCR2A = 0;
  TCCR2B = 0;

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

  TCNT2 = 0;          // set counter to zero

  // Reset prescalers
  GTCCR = bit (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
}

ISR (TIMER2_COMPA_vect){
  // see if we have reached timing period
  if (++timerTicks < timerPeriod)
    return;

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;
  TIMSK2 = 0;    // disable Timer2 Interrupt
  counterReady = true;
  if(counterReady){
    Serial.print("Pulses_L: ");
    Serial.print(pulses_L);
    Serial.print("  Pulses_R: ");
    Serial.println(pulses_R);

    // multiplying by 100 to get a greater difference to compare
    revolutions_L_rpm = (pulses_L * 100) / pulsesperturn;
    revolutions_R_rpm = (pulses_R * 100) / pulsesperturn;

    // Total revolutions
//    revolutions_L = revolutions_L + (pulses_L / pulsesperturn);
//    revolutions_R = revolutions_R + (pulses_R / pulsesperturn);

    pulses_L = 0;
    pulses_R = 0;
  }
}

void requestEvent() {
  myData[0] = (revolutions_L_rpm >> 8) & 0xFF;
  myData[1] = revolutions_L_rpm & 0xFF;
  myData[2] = (revolutions_R_rpm >> 8) & 0xFF;
  myData[3] = revolutions_R_rpm & 0xFF;

  Wire.write(myData, 4); //Sent 4 bytes to master
}

void setup() {
  Serial.begin(9600);
  pinMode(encoder_in_L, INPUT);
  pinMode(encoder_in_R, INPUT);
  attachInterrupt(0, count_L, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_L, count_L, RISING);
  attachInterrupt(1, count_R, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_R, count_R, RISING);
  // Start the I2C Bus as Slave on address 9
  Wire.begin(9);
  // Attach a function to trigger when something is received.
  Wire.onRequest(requestEvent);
}

void loop() {
  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;

  startCounting (1000);  // how many ms to count for

  while (!counterReady)
     { }  // loop until count over

  // Print out rpm
  Serial.print("Left motor rps: ");
  Serial.println(revolutions_L_rpm);
  Serial.print("Right motor rps: ");
  Serial.println(revolutions_R_rpm);

//  Print out revolutions
//  Serial.print("Left motor revolution count: ");
//  Serial.println(revolutions_L);
//  Serial.print("Right motor revolution count: ");
//  Serial.println(revolutions_R);


  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  delay(200);
}
#包括
#包括
//包括I2C所需的导线库
#包括
//针脚17上的RX(至S2),针脚16上的TX(至S1)。
软件串行SWSerial(非插脚,16);
//使用SWSerial作为串行端口。
剑齿石(SWSerial);
//////////////////编码器数据//////////////////
无符号整数转/分=0;
无符号整数转/分=0;
int16_t x=0;
int16_t y=0;
////////////////////////////////////////////////
//////////////调整变量//////////////
整数误差=0;
int kp=12;
调整后的整数=0;
////////////////////////////////////////////////
////////////////////马达//////////////////////
//申报arduino引脚
int-LEDg=7;
int-LEDr=6;
int-LEDy=5;
int-speedVar=0;
int-speedOne=0;
int-speedTwo=0;
整数幂;
////////////////////结束/////////////////////////
无效设置(){
//初始化引脚的模式
引脚模式(LEDg,输出);
引脚模式(发光二极管,输出);
pinMode(发光二极管,输出);
//设置串行通信速率
Serial.begin(9600);
SWSerial.begin(9600);
Wire.begin();
}
void循环()
{
//检查arduino是否接收到信号
如果(Serial.available()>0){
char val=Serial.read();//读取信号
连续打印(“接收:”);
序列号println(val);
开关(val){
/*********只要e(三角形)保持不变,则将速度提高1*********/
案例“a”:
前进();
打破
/*********只要g(x)保持不变,就将速度降低1*********/
案例“c”:
反向();
打破
/*********只要e(三角形)保持不变,则将速度提高1*********/
案例“d”:
左转();
打破
/*********只要g(x)保持不变,就将速度降低1*********/
案例“b”:
右转();
打破
/*********当圆圈保持5秒时切换*********/
案例“f”:
切换开关(LEDy);
打破
/*********按住Square键5秒时切换*********/
案例“h”:
停止马达();
打破
}
Serial.print(“sppedVar=”);
串行打印(speedVar);
Serial.print(“\t速度:”);
串行打印(speedOne);
串行打印(“\trightSpeed:”);
Serial.println(speedTwo);
}
Wire.requestFrom(9,4);//从从arduino(9)请求4个字节
字节a=Wire.read();
序列号。打印(“a:”);
连续打印(a);
字节b=Wire.read();
序列号。打印(“b:”);
连续打印(b);
字节e=Wire.read();
连续打印(“--e:”);
连续打印(e);
字节f=Wire.read();
连续打印(“f:”);
连续打印(f);
x=a;
x=(x>8)&0xFF;
myData[1]=每分钟转数&0xFF;
myData[2]=(转速>>8)和0xFF;
myData[3]=每分钟转数&0xFF;
Wire.write(myData,4);//已将4个字节发送给master
}
无效设置(){
Serial.begin(9600);
pinMode(编码器输入);
pinMode(编码器输入);
attachInterrupt(0,计数,上升);//attachInterrupt(数字插脚到中断(编码器,计数,上升);
attachInterrupt(1,计数,上升);//attachInterrupt(数字插脚到中断(编码器,计数,上升);
//将I2C总线作为地址9上的从机启动
开始(9);
//附加一个函数以在接收到某个内容时触发。
onRequest(requestEvent);
}
void循环(){
//停止计时器0会中断计数
字节oldtcr0a=TCCR0A;
字节oldtcr0b=TCCR0B;
TCCR0A=0;//停止计时器0
TCCR0B=0;
开始计算(1000);//要计算多少毫秒
而(!准备就绪)
{}//循环,直到计数结束
//打印输出转速
串行打印(“左马达转速:”);
Serial.println(转/分);
串行打印(“右马达rps:”);
Serial.println(转/分);
//打印革命
//串行打印(“左马达旋转计数:”);
//连续打印(转数);
//串行打印(“右马达旋转计数:”);
//连续打印(转数);
//重新启动计时器0
TCCR0A=旧TCCR0A;
TCCR0B=旧TCCR0B;
延迟(200);
}