极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19449|回复: 9

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

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

使用道具 举报

 楼主| 发表于 2016-6-18 00:23:36 | 显示全部楼层
我调程序后可以将两个传感器数据在串口上显示,现在就是不明白怎么编程把这些数据用nrf24l01进行传输
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-18 10:17:59 | 显示全部楼层
有大神知道怎么把一个传感器的数据通过nrf24l01模块传到另一个nrf24l01模块再通过串口读出来
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[2] = {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[1];  //读取数组第二个元素中的数值
      counter_val[1] = 0;     //读完清除原来的数值,以便下次使用
    }
    else   //当前使用的是奇数计数器,则上次频率值存放在第一个元素中
    {
      lTemp = counter_val[0];  //读取数组第二个元素中的数值
      counter_val[0] = 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[CurCnt & 0x01] += 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[2];
    byte data[Mirf.payload];

    //adata是unsigned int双字节数据,必须拆开。
    //将adata高低八位拆分:
    data[0] = adata & 0xFF;                //低八位给data[0],
    data[1] = adata >> 8;    //高八位给data[1]。
    data[2] = bdata & 0xFF;                //低八位给data[0],
    data[3] = 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);
}
回复 支持 反对

使用道具 举报

发表于 2016-7-5 17:48:07 | 显示全部楼层
vikitinos 发表于 2016-6-18 20:21
这是测速模块和超声波测距模块一起运行的代码,就是无线模块的收发代码怎么写不知道
#include
#define U ...

我也在測試,用同樣方法還沒成功
回复 支持 反对

使用道具 举报

发表于 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 ...

请问你测速用的是什么模块???霍尔还是光耦模块??
回复 支持 反对

使用道具 举报

发表于 2016-12-4 22:04:13 | 显示全部楼层
linyballen 发表于 2016-7-6 17:05
今天測試OK,還傳了6組數據也OK。
Mirf.payload = 12;

你好,请问有具体的程序可以发出来给大家参考参考吗?
回复 支持 反对

使用道具 举报

发表于 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[Mirf.payload];
   if (!Mirf.isSending() && Mirf.dataReady())    //等待接收数据准备好
    {
        Mirf.getData(data);    //接收数据到data数组
       ax = (int16_t)((data[1] << 8) | data[0]);
       ay = (int16_t)((data[3] << 8) | data[2]);
       az = (int16_t)((data[5] << 8) | data[4]);
       gx = (int16_t)((data[7] << 8) | data[6]);
       gy = (int16_t)((data[9] << 8) | data[8]);
       gz = (int16_t)((data[11] << 8) | data[10]);      
            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(",");  
    }
}
回复 支持 反对

使用道具 举报

发表于 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[2];
    byte data[Mirf.payload];
    data[0] = ax & 0xFF; data[1] = ax >> 8;               
    data[2] = ay & 0xFF; data[3] = ay >> 8;
    data[4] = az & 0xFF; data[5] = az >> 8;   //高八位给data[1]。
    data[6] = gx & 0xFF; data[7] = gx >> 8;
    data[8] = gy & 0xFF; data[9] = gy >> 8;   //高八位给data[1]。
    data[10] =gz & 0xFF; data[11] = gz >> 8;

    //设置向"serv1"发送数据
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data);
    //while死循环等待发送完毕,才能进行下一步操作。
    while(Mirf.isSending()) {}
   delay(200);
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-27 03:12 , Processed in 0.043500 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表