vikitinos 发表于 2016-6-17 20:42:14

Arduino+nrf24l01采集测速模块以及超声波测距模块收集信息

刚刚接触Arduino,入手了两块Arduino Uno R3 板子 和两个nrf24l01收发模块,准备用其中一个Arduino板子连接超声波测距模块和电机测速的模块,再通过nrf24l01无线传输模块,将收集到是数据发送到另一个与PC机相连的Arduino板子,最终能在PC机上通过串口或者其他工具看到采集的数据。
基于此,我也看了些基础的Arduino板子和两个传感器模块的知识,现在能让单独的其中一个传感器正常工作(我指的是Arduino板子直接与pc机相连时),获得了暂时的成就感。
但进行到现在时却发现要让两个模块同时工作,并通过nrf24l01模块将数据发送到接收端,再由pc机读出 对我十分的困难,我尝试着把两个模块各自的程序整合到一起再运行,不知什么原因失败了。对于nrf24l01模块怎么收集Arduino上的信息也是一头雾水,网上有的只是一些简单的例程,多个模块同时运行的帖子基本没有,到现在也是挺无助的,所以再发一个帖子求助。希望大家能给我一些指点。

vikitinos 发表于 2016-6-18 00:23:36

我调程序后可以将两个传感器数据在串口上显示,现在就是不明白怎么编程把这些数据用nrf24l01进行传输

vikitinos 发表于 2016-6-18 10:17:59

有大神知道怎么把一个传感器的数据通过nrf24l01模块传到另一个nrf24l01模块再通过串口读出来

vikitinos 发表于 2016-6-18 20:21:12

这是测速模块和超声波测距模块一起运行的代码,就是无线模块的收发代码怎么写不知道
#include <TimerOne.h>
#define U_Pin 6
// 设定SR04连接的Arduino引脚
const int TrigPin = 2;
const int EchoPin = 3;
float distance;
int servopin=6;//定义舵机接口数字接口6
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量
int val;
void servopulse(int servopin,int myangle)//定义一个脉冲函数
{
pulsewidth=(myangle*11)+500;//将角度转化为500-2480的脉宽值
digitalWrite(servopin,HIGH);//将舵机接口电平至高
delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
digitalWrite(servopin,LOW);//将舵机接口电平至低
delay(20-pulsewidth/1000);
}
long counter_val = {0, 0}; //定义数组,用于存放外部中断计数值
byte CurCnt = 0;         //定义当前计数器标志,用于判断当前正在计数的数组
int j = 0;                        //定义定时器中断标志,用于判断是否发生中断
float Speed;//设置变量time,计时
void setup(){
Serial.begin(9600);

attachInterrupt(0, counter, RISING);
Timer1.initialize(100000); // 设置定时器中断时间,单位微秒,此处为0.1秒
Timer1.attachInterrupt( timerIsr ); // 打开定时器中断
interrupts();//打开外部中断
   pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
Serial.begin(9600);//连接到串行端口,波特率为9600
Serial.println("servu=o_seral_simple ready" ) ; // put your setup code here, to run once:

// 初始化串口通信及连接SR04的引脚
      Serial.begin(9600);
      pinMode(TrigPin, OUTPUT);
    // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态
      pinMode(EchoPin, INPUT);
    Serial.println("Ultrasonic sensor:");
}
void loop()
{
long lTemp = 0; //定义临时存储数据变量
if (j == 1) //判断是否发生定时器中断,即定时时间是否到达
{
    j = 0; //清除定时器中断标志位
    if ((CurCnt & 0x01) == 0) //当前使用的是偶数计数器,则上次频率值存放在第二个元素中
    {
      lTemp = counter_val;//读取数组第二个元素中的数值
      counter_val = 0;   //读完清除原来的数值,以便下次使用
    }
    else   //当前使用的是奇数计数器,则上次频率值存放在第一个元素中
    {
      lTemp = counter_val;//读取数组第二个元素中的数值
      counter_val = 0; //读完清除原来的数值,以便下次使用
    }
    Speed = (lTemp / 10) * 600;
    Serial.print("S");    //发送帧头大写S
    Serial.print( Speed);//发送频率数据,并回车换行
    Serial.print("rpm");
}

    val=Serial.read();//读取串行端口的值
if(val>'0'&&val<='9')
{
    val=val-'0';//将特征量转化为数值变量
    val=val*(180/9);//将数字转化为角度
    Serial.print("moving servo to ");
    Serial.print(val,DEC);
    Serial.println();
    for(int i=0;i<=50;i++)//给予舵机足够的时间让它转到指定角度
   {
      servopulse(servopin,val);//引用脉冲函数
      }
   } // put your main code here, to run repeatedly:

    // 产生一个10us的高脉冲去触发TrigPin
      digitalWrite(TrigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(TrigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(TrigPin, LOW);
    // 检测脉冲宽度,并计算出距离
      distance = pulseIn(EchoPin, HIGH) / 58.00;
      Serial.print(distance);
      Serial.print("cm");
      Serial.println();
      delay(1000);
}
void counter()
{
//通过当前计数器来实现对外部中断计数值存储的切换
counter_val += 1;   //发生一次中断则加1
}
void timerIsr()
{
j = 1;   //置位定时器中断标志位
CurCnt++; //当前计数器的值加1,实现另一个计数值切换
}





这是论坛里找的nrf24l01的代码,可以稍微改一下再套用吗?
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup()
{
    Serial.begin(9600);

    Mirf.cePin = 8;                //设置CE引脚为D9
    Mirf.csnPin = 7;      //设置CE引脚为D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();//初始化nRF24L01               

      //设置接收标识符"Sen01"
    Mirf.setRADDR((byte *)"Sen01");
    Mirf.payload = sizeof(unsigned int);//在这把2 修改成4
    Mirf.channel = 3;
    Mirf.config();

      //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
      //这里标识写入了Sender.ino
    Serial.println("I'm Sender...");
}
unsigned int adata = 0,bdata = 0;

void loop()
{
      //读取值到adata
    adata = speed;
    bdata = distance;

    //由于nRF24L01只能以byte单字节数组形式发送Mirf.payload个数据,
    //所以必须将所有需要传输的数据拆成byte。
    //下面定义byte数组,存放待发数据,因为Mirf.payload = sizeof(unsigned int);
    //实际下面等于byte data;
    byte data;

    //adata是unsigned int双字节数据,必须拆开。
    //将adata高低八位拆分:
    data = adata & 0xFF;                //低八位给data,
    data = adata >> 8;    //高八位给data。
    data = bdata & 0xFF;                //低八位给data,
    data = bdata >> 8;
    //设置向"serv1"发送数据
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data);
    //while死循环等待发送完毕,才能进行下一步操作。
    while(Mirf.isSending()) {}
    Serial.println(adata);
    Serial.print("*****");
    Serial.println(bdata,DEC);
    delay(3000);
}

linyballen 发表于 2016-7-5 17:48:07

vikitinos 发表于 2016-6-18 20:21 static/image/common/back.gif
这是测速模块和超声波测距模块一起运行的代码,就是无线模块的收发代码怎么写不知道
#include
#define U ...

:)我也在測試,用同樣方法還沒成功

linyballen 发表于 2016-7-6 17:05:36

:)今天測試OK,還傳了6組數據也OK。
Mirf.payload = 12;

下水道 发表于 2016-9-30 13:33:04

vikitinos 发表于 2016-6-18 20:21
这是测速模块和超声波测距模块一起运行的代码,就是无线模块的收发代码怎么写不知道
#include
#define U ...

请问你测速用的是什么模块???霍尔还是光耦模块??

jianwei569 发表于 2016-12-4 22:04:13

linyballen 发表于 2016-7-6 17:05
今天測試OK,還傳了6組數據也OK。
Mirf.payload = 12;

你好,请问有具体的程序可以发出来给大家参考参考吗?

linyballen 发表于 2016-12-14 14:46:35

jianwei569 发表于 2016-12-4 22:04
你好,请问有具体的程序可以发出来给大家参考参考吗?

RECEIVER端:
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <SoftwareSerial.h>   // 引用程式庫
int16_t ax, ay, az;
int16_t gx, gy, gz;
SoftwareSerial BT(8, 9); // 接收腳, 傳送腳定義連接藍牙模組的序列埠
void setup()
{
    Serial.begin(115200);
       BT.begin(115200);
    //---------初始化部分,不可随时修改---------
    Mirf.cePin = 6;   //设置CE引脚为D9
    Mirf.csnPin = 10;   //设置CE引脚为D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();//初始化nRF24L01

    //---------配置部分,可以随时修改---------
    //设置接收标识符"Rev01"
    Mirf.setRADDR((byte *)"Rec01");
    //设置一次收发的字节数,这里发一个整数,
    //写sizeof(unsigned int),实际等于2字节
    Mirf.payload =12;
    //发送通道,可以填0~128,收发必须一致。
    Mirf.channel = 2;
    Mirf.config();

    Serial.println("I'm Receiver...");
}

void loop()
{
    byte data;
   if (!Mirf.isSending() && Mirf.dataReady())    //等待接收数据准备好
    {
      Mirf.getData(data);    //接收数据到data数组
       ax = (int16_t)((data << 8) | data);
       ay = (int16_t)((data << 8) | data);
       az = (int16_t)((data << 8) | data);
       gx = (int16_t)((data << 8) | data);
       gy = (int16_t)((data << 8) | data);
       gz = (int16_t)((data << 8) | data);      
            Serial.print("ax="); Serial.print(ax); Serial.print("\t");
            Serial.print("ay="); Serial.print(ay); Serial.print("\t");
            Serial.print("az="); Serial.print(az); Serial.print("\t");
            Serial.print("gx="); Serial.print(gx); Serial.print("\t");
            Serial.print("gy="); Serial.print(gy); Serial.print("\t");
            Serial.print("gz="); Serial.println(gz);
      BT.print("E");
      BT.print(ax);       BT.print(",");
      BT.print(ay);       BT.print(",");
      BT.print(az);       BT.print(",");
      BT.print(gx);       BT.print(",");
      BT.print(gy);       BT.print(",");
      BT.println(gz);    // BT.print(",");
    }
}

linyballen 发表于 2016-12-14 14:48:17

jianwei569 发表于 2016-12-4 22:04
你好,请问有具体的程序可以发出来给大家参考参考吗?

Sender端:
#include "I2Cdev.h"
#include "MPU6050.h"
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
#define OUTPUT_READABLE_ACCELGYRO
#define LED_PIN 13
bool blinkState = false;
void setup()
{
   #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
      Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
      Fastwire::setup(400, true);
    #endif
    Serial.begin(115200);
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
   pinMode(LED_PIN, OUTPUT);
    Mirf.cePin = 9;                //设置CE引脚为D9
    Mirf.csnPin = 10;        //设置CE引脚为D10
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();//初始化nRF24L01               

        //设置接收标识符"Sen01"
    Mirf.setRADDR((byte *)"Sen01");
    //设置一次收发的字节数,这里发一个整数,写sizeof(unsigned int),实际等于2字节
    Mirf.payload =12;
    //发送通道,可以填0~128,收发必须一致。
    Mirf.channel = 2;
    Mirf.config();

        //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
        //这里标识写入了Sender.ino
    Serial.println("I'm Sender...");
}
void loop()
{
   accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
   #ifdef OUTPUT_READABLE_ACCELGYRO
      Serial.print("a/g:\t");
      Serial.print(ax); Serial.print("\t");
      Serial.print(ay); Serial.print("\t");
      Serial.print(az); Serial.print("\t");
      Serial.print(gx); Serial.print("\t");
      Serial.print(gy); Serial.print("\t");
      Serial.println(gz);
    #endif
      #ifdef OUTPUT_BINARY_ACCELGYRO
      Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
      Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
      Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
      Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
      Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
      Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif
    //由于nRF24L01只能以byte单字节数组形式发送Mirf.payload个数据,
    //所以必须将所有需要传输的数据拆成byte。
    //下面定义byte数组,存放待发数据,因为Mirf.payload = sizeof(unsigned int);
    //实际下面等于byte data;
    byte data;
    data = ax & 0xFF; data = ax >> 8;               
    data = ay & 0xFF; data = ay >> 8;
    data = az & 0xFF; data = az >> 8;   //高八位给data。
    data = gx & 0xFF; data = gx >> 8;
    data = gy & 0xFF; data = gy >> 8;   //高八位给data。
    data =gz & 0xFF; data = gz >> 8;

    //设置向"serv1"发送数据
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data);
    //while死循环等待发送完毕,才能进行下一步操作。
    while(Mirf.isSending()) {}
   delay(200);
}
页: [1]
查看完整版本: Arduino+nrf24l01采集测速模块以及超声波测距模块收集信息