Are Aduino's Legal

Is it legal to use an adruino on our robot this year (2017)? We have arduino code to use with our LIDAR system, but we are having a hard time implementing it in LabVIEW… If we can just interface the aduino with the roboRIO, it would be much easier and less time consuming.
Thanks

I believe so, I haven’t come across any rule against it.

This would fall under the custom circuit and computing device rule(s). As long as you don’t control any motors or other moving devices you should be just fine.

Directly control. It is technically legal to do all of your code on an external cpu and just have the roborio pass commands to the motors.

Not sure what lidar you are using, but a couple of years ago we got a Lidar-Lite, (v2?) and had fits trying to get the I2C interface working (even having I2C background on other systems).

We tried the lidar-lite’s PWM and it had its share of glitches too. We didn’t want to deal with this nonsense in the roborio code, so we bolted the lidar to a little plastic box, put an arduino micro in the box, had the arduino read the PWM, clean up the errors, and simply drive a little DAC output. So the sensor just looked like an analog input to the roborio and the kids didn’t need to code for all the buggy data cases. Yeah, yeah, maybe went from 1cm accuracy to 3cm, but was not an issue for us. The analog in was easy to use on the roborio. After all that, they ended up not using it :frowning:

As much as we love Limor’s stuff, today we would probably use a teesny LC (or a little PIC) and not the larger arduino micro, but either way here is the code we used on the arduino micro:

//  LidarLite_PWM_Read  --  Feb 2015 gcs
//
//  Lidar Lite claims to read to about 40 to 60 meters, with about 1cm accuracy.
//  PWM out pin, with pulldown of about 3.3K, will have 10 us/cm pulse width:  1m = 1 ms...
//  Close-in (< ~ 0.5m) seems to have more error than further out.
//  BUG:  the PWM output can go away with some measurements (eg: close-in sweeps), and need a reset (enable low/high).
//  This is said to be fixed in current firmware, but we will just watch for it here, and reset unit as needed.
//  I2C interface not used here -- will use PWM out, measure with arduino, and output analog voltage via DAC.
//  Beamwidth said to be about 1/2 degree, so at 1 meter it is only about 9mm dia. At 10 meters, beamwidth ~= 9 cm (~ 3.5").
//  Apparently, due to the signal processing used, multiple Lidar Lites could point at same target without interference.
//  The zero reference is the pcb surface at the connector.
//
//  Will use Microchip MCP4725 12-bit I2C dac, running on 5V.
//  Currently using MCP4725A0 with address at 0x60 (A=0) or 0x61 (A=1).  (A0, A2)
//  Can also use MCP4725A1 with address at 0x62 (A=0) or 0x63 (A=1).     (A4, A6)
//  Can also use MCP4725A2 with address at 0x64 (A=0) or 0x65 (A=1).     (A8, AA)
//  Depending on sensitivity (and max sensing distance) desired, we can configure it for one of four cases.  
//  For FIRST, we will set it to sensitivity of 4 mV/cm, for a max sensing distance of 12.5 m (41 ft).
//  (1m = 3.28 ft)
//
//  DAC-Sensitivity    Max-Distance      Equivalent     DAC_CONVERSION    PWM_MAX_US
//  ---------------    ------------      ----------     --------------    ----------
//      1 mV/cm        50.0 m (164 ft)    0.1 mV/us          8192           50000
//      2 mV/cm        25.0 m (82 ft)     0.2 mV/us         16384           25000
//      4 mV/cm        12.5 m (41 ft)     0.4 mV/us         32768           12500
//      8 mV/cm        6.25 m (20.5 ft)   0.8 mV/us         65536           6250
//
//  For Vout = 1 mV/cm sensitivity:  max data D is 0 to 4095 ~= 5V = 50.0 meters max, and:
//      Equivalently, Vout = (1 mV/cm)(1 cm/10 us) = 0.1 mV/us
//      Vout = (5V)(D)/4096,  so:
//      D = (4096/5000 mV)(Vout) = (4096/5000 mV)(0.1 mV/us) = 8192/(100000 us)
//  For Vout = 2 mV/cm sensitivity:  max data D is 0 to 4095 ~= 5V = 25.0 meters max, and:
//      D = 16384/(100000 us)
//  For Vout = 4 mV/cm sensitivity:  max data D is 0 to 4095 ~= 5V = 12.5 meters max, and:
//      D = 32768/(100000 us)
//  For Vout = 8 mV/cm sensitivity:  max data D is 0 to 4095 ~= 5V = 6.25 meters max, and:
//      D = 65536/(100000 us)

// this sets dac sensitivity and max range:
#define DAC_CONVERSION       32768      // dac_data = (DAC_CONVERSION * pwm_microseconds + 50000)/100000

// number of pwm samples to use in moving-average filter -- higher numbers slow response time (5 seems good)
#define NUM_PWM_AVG          5 

#define MCP4725_ADDR         0x60
#define LIDAR_DEBUG          0

#include <Wire.h>

int      lidar_pwm = A4;                // pin A4 is pwm input
int      lidar_enable = A5;             // pin A5 is enable (reset/) input
int      pwm_monitor = 12;              // pin 12 is pwm monitor output (after filtering)

unsigned long pwm_microseconds;
unsigned long pwm_microsec_avg;
unsigned int  dac_data;
unsigned int  i;

unsigned long pwm_buf[NUM_PWM_AVG];     // pwm_buf is circular buffer for NUM_PWM_AVG most-recent readings
unsigned long *pwm_buf_wr;              // write pointer for pwm_buf


void setup() 
{
  Wire.begin(); 
  Serial.begin(115200);
  pinMode(lidar_pwm, INPUT);
  pinMode(lidar_enable, OUTPUT);
  pinMode(pwm_monitor, OUTPUT);
  
  pwm_buf_wr = pwm_buf;                 // reset write pointer to start of pwm_buf
  
  for (i=0;  i<NUM_PWM_AVG; i++)        // clear pwm_buf
    pwm_buf* = 0;
    
  digitalWrite(pwm_monitor, LOW);       // monitor pin low
  digitalWrite(lidar_enable, HIGH);     // turn sensor on

  dac_write(0x0000);                    // init dac to zero V
  
  Serial.println("LidarLite_PWM_Read");
}

void loop() 
{
  // lidar pwm period varies from about 12 ms to 25 ms -- set read timeout to 1 sec:
  // (returns microseconds -- 1000 us = 1 meter)
  // (returns 0 if no pulse before timeout)
  pwm_microseconds = pulseIn(lidar_pwm, HIGH, 1000000);    
  
  // ===== if we got a valid pulse-width reading:
  if( (pwm_microseconds != 0) && (pwm_microseconds < 50000) )  // zero pulse and fat pulse both bogus, so trap
  { 
    // --- add current distance pwm reading to circular buffer:
    *pwm_buf_wr++ = pwm_microseconds;              // add current reading to buffer, and inc ptr
    if (pwm_buf_wr == (pwm_buf + NUM_PWM_AVG))     // did write ptr wrap?
      pwm_buf_wr = pwm_buf;                        // if so, reset it to start of buffer

    // --- moving-average filter to smooth out the readings:
    pwm_microsec_avg = 0;
    for (i=0;  i<NUM_PWM_AVG; i++)
      pwm_microsec_avg += pwm_buf*;
    pwm_microsec_avg /= NUM_PWM_AVG;
   
    // --- convert to dac data based on conversion sensitivity defined:
    dac_data = (int)( (DAC_CONVERSION * pwm_microsec_avg + 50000) / 100000 );
    if (dac_data > 4095)                          // if over range, clamp to limit for 12-bit dac
      dac_data = 4095;
    
    #if (LIDAR_DEBUG)
      // --- pwm monitor pin to see effect of moving-avg filter:
      digitalWrite(pwm_monitor, HIGH);
      delayMicroseconds(pwm_microsec_avg);
      digitalWrite(pwm_monitor, LOW);
      // --- dump:
      Serial.print(pwm_microseconds);
      Serial.print("   ");
      Serial.print(pwm_microsec_avg);
      Serial.print("   ");
      Serial.println(dac_data);
    #endif
    
    dac_write(dac_data);
  }
  // ===== else the lidar may have locked-up, so reset it:
  else  
  {
    digitalWrite(lidar_enable, LOW);      // turn off (and reset) the sensor
    delay(1);
    digitalWrite(lidar_enable, HIGH);     // turn the sensor back on
    delay(1);
    Serial.println("reset");
  }
  
  #if (LIDAR_DEBUG)
    delay(1);                             // 1 ms delay for serial dump
  #endif
}

// ---------------------------------
void dac_write(uint16_t dat)
{
  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write( (uint8_t)((dat >> 8) & 0x000F) );
  Wire.write( (uint8_t)(dat & 0x00FF) );
  Wire.endTransmission(); 
}

**