/// <summary> /// Write data to the specified device 7 bit address. /// Example: Write(0x1D, new byte [] { 127, 64 } ); /// </summary> public async void Write(byte deviceAddress, params byte[] data) { if (data.Length == 0) { throw new Exception("I2C Data for Write cannot be empty"); } if (data.Length > 255) { throw new Exception("Can not send more than 255 bytes over I2C"); } byte writeAddress8Bit; if (deviceAddress >= 128) { writeAddress8Bit = deviceAddress; } else { writeAddress8Bit = (byte)(deviceAddress << 1); } List <byte> bl = new List <byte>(); bl.Add(writeAddress8Bit); bl.Add((byte)data.Length); bl.AddRange(data); await _ezb.sendCommand(0, EZB.CommandEnum.CmdI2CWrite, bl.ToArray()); }
/// <summary> /// Stop /// </summary> public void Stop() { if (_ezb.EZBType != EZB.EZ_B_Type_Enum.ezb3) { throw new Exception("This feature is only compatible with EZ-B v3"); } List <byte> b = new List <byte>(); b.Add((byte)EZB.CmdEZBv3Enum.CmdV3BV4113); b.Add((byte)4); _ezb.sendCommand(0, EZB.CommandEnum.CmdEZBv3, b.ToArray()); }
/// <summary> /// Set the status of a digital port. TRUE will output +5, FALSE will short to GND /// </summary> /// <returns>True if successful</returns> public void SetDigitalPort(DigitalPortEnum digitalPort, bool status) { int index = (int)digitalPort; _lastValue[index] = status; if (status) { _ezb.sendCommand(EZB.CommandEnum.CmdSetDigitalPortOn + (byte)digitalPort); } else { _ezb.sendCommand(EZB.CommandEnum.CmdSetDigitalPortOff + (byte)digitalPort); } }
/// <summary> /// Get an integer from 0-255 (8 bits) representing the relative voltage of a specified ADC port (Between 0 and 5 volts) /// </summary> public async Task <int> GetADCValue(ADCPortEnum sendSensor) { int index = (int)sendSensor; int retVal; if (_ezb.EZBType == EZB.EZ_B_Type_Enum.ezb4) { retVal = (UInt16)BitConverter.ToUInt16(await _ezb.sendCommand(2, EZB.CommandEnum.CmdGetADCValue + (byte)sendSensor), 0) / 16; } else { retVal = (await _ezb.sendCommand(1, EZB.CommandEnum.CmdGetADCValue + (byte)sendSensor))[0]; } return(retVal); }
/// <summary> /// Send the dynamixel data packet to the ez-b b4 /// </summary> public void SendCommandToEZB(byte[] data) { List <byte> cmd = new List <byte>(); cmd.Add((byte)EZB.CmdEZBv4Enum.CmdV4SetAX12Servo); cmd.Add((byte)data.Length); cmd.AddRange(data); _ezb.sendCommand(EZB.CommandEnum.CmdEZBv4, cmd.ToArray()); }
/// <summary> /// Release servo. Release a servo from holding its position. /// If modified, stops the servo. /// </summary> public async Task ReleaseServo(ServoPortEnum servoPort) { _servoLastMoveTime[(int)servoPort] = DateTime.Now; _servoReleased[(int)servoPort] = true; if (servoPort >= ServoPortEnum.D0 && servoPort <= ServoPortEnum.D23) { await _ezb.sendCommand(EZB.CommandEnum.CmdSetServoPosition + (byte)servoPort, new byte[] { (byte)0 }); } else if (servoPort >= ServoPortEnum.AX0 && servoPort <= ServoPortEnum.AX50 && _ezb.EZBType == EZB.EZ_B_Type_Enum.ezb4) { byte id = (byte)(servoPort - ServoPortEnum.AX0); List <byte> cmdData = new List <byte>(); cmdData.Add((byte)EZB.CommandEnum.CmdEZBv4); cmdData.Add((byte)EZB.CmdEZBv4Enum.CmdV4SetAX12Servo); byte[] cmd = Dynamixel.ReleaseServo(id); cmdData.Add((byte)cmd.Length); cmdData.AddRange(cmd); await _ezb.sendCommandData(0, cmdData.ToArray()); } else if (servoPort >= ServoPortEnum.AXV0 && servoPort <= ServoPortEnum.AXV50 && _ezb.EZBType == EZB.EZ_B_Type_Enum.ezb4) { byte id = (byte)(servoPort - ServoPortEnum.AXV0); List <byte> cmdData = new List <byte>(); cmdData.Add((byte)EZB.CommandEnum.CmdEZBv4); cmdData.Add((byte)EZB.CmdEZBv4Enum.CmdV4SetAX12Servo); byte[] cmd = DynamixelV2.ReleaseServo(id); cmdData.Add((byte)cmd.Length); cmdData.AddRange(cmd); await _ezb.sendCommandData(0, cmdData.ToArray()); } }
/// <summary> /// Get the value received from the HC-SR04 Ping Sensor /// </summary> public async Task <int> GetValue(Digital.DigitalPortEnum triggerPort, Digital.DigitalPortEnum echoPort) { int index = (int)triggerPort; if (lastRequest[index].AddMilliseconds(MinPoolTimeMS) > DateTime.Now) { return(lastValue[index]); } byte retVal = (await _ezb.sendCommand(1, EZB.CommandEnum.CmdHC_SR04 + (byte)triggerPort, (byte)echoPort))[0]; lastValue[index] = retVal; lastRequest[index] = DateTime.Now; return(retVal); }
/// <summary> /// Specify the clock delay between bytes in cycles of the EZ-B's 120mhz 32 Bit ARM processor. This would only need to be used to fine tune the baudrate timing if the connected device is not very accurate or requires a diffference in timing. /// For example, some open-source hardware platforms use Software Serial drivers, which sometimes need a little bit of tweaking. Generally, you should never need to change these values. /// However, there is a Custom labelled baudrate which you can change for specific speeds. /// Anyone adjusting these speeds will need a logic analyzer, such as the Saleae Logic16 or Logic32 /// </summary> public void SetBaudClock(BAUD_RATE_ENUM baudRate, int clockSpeed) { if (!_ezb.IsConnected) { throw new Exception("Not connected"); } if (_ezb.EZBType != EZB.EZ_B_Type_Enum.ezb4) { throw new Exception("This feature is only available for EZ-B v4"); } List <byte> send = new List <byte>(); send.Add((byte)EZB.CmdEZBv4Enum.CmdV4UARTClockSpeed); send.Add((byte)baudRate); send.AddRange(BitConverter.GetBytes((UInt16)clockSpeed)); _ezb.sendCommand(EZB.CommandEnum.CmdEZBv4, send.ToArray()); }
private async Task _threadAudio_DoWork(Object sender, DoWorkEventArgs e) { try { if (OnStartPlaying != null) { OnStartPlaying(); } await _ezb.sendCommand(EZB.CommandEnum.CmdSoundStreamCmd, (byte)EZB.CmdSoundv4Enum.CmdSoundInitStop); bool playing = false; int position = 0; _sw.Restart(); _threadProgress.RunWorkerAsync(); do { byte[] bTmp = new byte[PACKET_SIZE]; int bytesRead = _ms.Read(bTmp, 0, PACKET_SIZE); position += bytesRead; byte[] bArray = new byte[bytesRead]; bool isClipping = false; int highest = 0; int lowest = 255; int average = 0; long total = 0; decimal volumeMultiplier = Volume / 100m; for (int x = 0; x < bytesRead; x++) { decimal newVal = (decimal)bTmp[x]; if (newVal > 128) { newVal = Math.Max(128, 128 + ((newVal - 128) * volumeMultiplier)); } else if (newVal < 128) { newVal = Math.Min(128, 128 - ((128 - newVal) * volumeMultiplier)); } if (newVal > 255) { newVal = 255; isClipping = true; } else if (newVal < 0) { newVal = 0; isClipping = true; } highest = Math.Max(highest, (int)newVal); lowest = Math.Min(lowest, (int)newVal); total += (int)newVal; bArray[x] = (byte)newVal; } average = (int)(total / bytesRead); List <byte> dataTmp = new List <byte>(); dataTmp.Add((byte)EZB.CmdSoundv4Enum.CmdSoundLoad); dataTmp.AddRange(BitConverter.GetBytes((UInt16)bArray.Length)); dataTmp.AddRange(bArray); await _ezb.sendCommand(EZB.CommandEnum.CmdSoundStreamCmd, dataTmp.ToArray()); if (!playing && position > PREBUFFER_SIZE) { await _ezb.sendCommand(EZB.CommandEnum.CmdSoundStreamCmd, (byte)EZB.CmdSoundv4Enum.CmdSoundPlay); playing = true; } if (OnAudioDataChanged != null) { OnAudioDataChanged(dataTmp.ToArray(), lowest, highest, average); } if (OnClippingStatus != null) { OnClippingStatus(isClipping); } float runtime = (float)_sw.ElapsedMilliseconds; float shouldSend = ((runtime * AUDIO_SAMPLE_BITRATE) / 1000) + PREBUFFER_SIZE; float difference = position - shouldSend; if (difference > 0) { float delay = (difference / AUDIO_SAMPLE_BITRATE) * 1000; await Task.Delay((int)delay); } } while (position < _ms.Length && _ezb.IsConnected && !_threadAudio.CancellationPending); } catch (Exception ex) { _ezb.Log(false, "Error Streaming Audio: {0}", ex); } }