/// <summary> /// Releases all resource used by the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/> object. /// </summary> /// <remarks> /// Call <see cref="Dispose"/> when you are finished using the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/>. The /// <see cref="Dispose"/> method leaves the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/> in an unusable state. After /// calling <see cref="Dispose"/>, you must release all references to the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/> /// so the garbage collector can reclaim the memory that the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/> was occupying. /// </remarks> public void Dispose() { if (this._isDisposed) { return; } this._channel = AdcChannels.None; if (this._chipSelect != null) { this._chipSelect.Dispose(); this._chipSelect = null; } if (this._clock != null) { this._clock.Dispose(); this._clock = null; } if (this._masterInSlaveOut != null) { this._masterInSlaveOut.Dispose(); this._masterInSlaveOut = null; } if (this._masterOutSlaveIn != null) { this._masterOutSlaveIn.Dispose(); this._masterOutSlaveIn = null; } this._isDisposed = true; }
/// <summary> /// Reads a packet from the specified register over the specified channel. /// </summary> /// <param name="channel"> /// The channel to comunicate with the target on. /// </param> /// <param name="register"> /// The register to read the packet from. /// </param> /// <exception cref="IOException"> /// Failed to read from register. /// </exception> public static Byte Read(AdcChannels channel, Byte register) { Byte[] packet = new Byte[3]; packet[0] = (Byte)(DEFAULT_ADDRESS | READ_FLAG); packet[1] = register; packet[2] = 0x00; // We init null and then wiringPiSPIDataRW will assign. // Convert byte array to char array to make wiringPiSPIDataRW happy. Char[] packetData = new Char[packet.Length]; for (Int32 i = 0; i <= (packetData.Length - 1); i++) { packetData[i] = (Char)packet[i]; } Array.Clear(packet, 0, packet.Length); Int32 result = UnsafeNativeMethods.wiringPiSPIDataRW((Int32)channel, packetData, packetData.Length); if (result >= 0) { // Success. wiringPiSPIDataRW will have assigned the // the value read on the packet buffer. return((Byte)packet[2]); } String chstr = Enum.GetName(typeof(AdcChannels), channel); throw new IOException("Failed to read SPI bus on channel " + chstr, result); }
/// <summary> /// Initializes a new instance of the <see cref="CyrusBuilt.MonoPi.SPI.MCP3008"/> /// class the analog-to-digital channel, clock pin, SPI Master Output/ /// Slave Input (MOSI), SPI Master Input/Slave Output (MISO), and SPI /// chip select pin. /// </summary> /// <param name="channel"> /// MCP3008 channel number 0 - 7 (pin 1 -8 on chip). /// </param> /// <param name="spiclk"> /// SPI clock pin. /// </param> /// <param name="mosi"> /// Master Output, Slave Input (MOSI). /// </param> /// <param name="miso"> /// Master Input, Slave Output (MISO). /// </param> /// <param name="cs"> /// Chip Select pin. /// </param> public MCP3008(AdcChannels channel, GpioBase spiclk, GpioBase mosi, GpioBase miso, GpioBase cs) { this._channel = channel; this._clock = spiclk; this._masterOutSlaveIn = mosi; this._masterInSlaveOut = miso; this._chipSelect = cs; }
/// <summary> /// Gets the file descriptor for the given channel. /// </summary> /// <returns> /// If successful, the file descriptor; Otherwise, -1. /// </returns> /// <param name="channel"> /// The channel to get the descriptor for. /// </param> public static Int32 GetFileDescriptor(AdcChannels channel) { Int32 descriptor = -1; if (_initialized) { if ((channel == AdcChannels.Channel0) || (channel == AdcChannels.Channel1)) { descriptor = UnsafeNativeMethods.wiringPiSPIGetFd((Int32)channel); } } return(descriptor); }
/// <summary> /// Open the SPI device and set it up, etc. /// </summary> /// <param name="channel"> /// The channel to open. /// </param> /// <param name="speed"> /// The speed to negotiate the transfer rate at (ie. 38400). /// </param> public static Boolean Init(AdcChannels channel, Int32 speed) { if (_initialized) { return true; } if ((channel == AdcChannels.Channel0) || (channel == AdcChannels.Channel1)) { _initialized = (UnsafeNativeMethods.wiringPiSPISetup((Int32)channel, speed) == 0); } else { _initialized = false; } return _initialized; }
private static void Stm32Ads1220_AcquisitionDataReceived(object sender, AcquisitionEventArgs e) { Trace("App DataReceived"); if (!AdcChannels.ContainsKey(e.Channel)) { bool added = AdcChannels.TryAdd( e.Channel, new AdcChannel(e.Channel, (int)Math.Ceiling(Settings.Default.AcquisitionDuration * Settings.Default.AcquisitionSpeed), Settings.Default.Average, Settings.Default.AcquisitionSpeed ) ); if (added) { AdcChannels[e.Channel].DropPoints = Settings.Default.AcqDropPoints; AdcChannels[e.Channel].CalculatedXColumnSelector = x => CsvExporter.OADateToSeconds(x); if (ChannelEnable.ContainsKey(e.Channel)) { AdcChannels[e.Channel].IsVisible = ChannelEnable[e.Channel]; } if (ChannelNames.ContainsKey(e.Channel)) { AdcChannels[e.Channel].Name = ChannelNames[e.Channel]; } if (ColorSet.ContainsKey(e.Channel)) { AdcChannels[e.Channel].Color = ColorSet[e.Channel]; } if (ChannelMathY.ContainsKey(e.Channel)) { AdcChannels[e.Channel].MathExpressionY = ChannelMathY[e.Channel]; } new Thread(() => { NewChannelDetected?.Invoke(Stm32Ads1220, new NewChannelDetectedEventArgs(e.Channel)); }).Start(); } else { Logger.Error(Default.msgAdcChannelConcurrency); return; } } AdcChannels[e.Channel].AddPoint(e.Value); if (!AutosaveTimer.Enabled) { AutosaveTimer.Start(); } }
/// <summary> /// Initializes a new instance of the <see cref="CyrusBuilt.MonoPi.IO.SPI.MCP3008"/> /// class the analog-to-digital channel, clock pin, SPI Master Output/ /// Slave Input (MOSI), SPI Master Input/Slave Output (MISO), and SPI /// chip select pin. /// </summary> /// <param name="channel"> /// MCP3008 channel number 0 - 7 (pin 1 -8 on chip). /// </param> /// <param name="spiclk"> /// SPI clock pin. /// </param> /// <param name="mosi"> /// Master Output, Slave Input (MOSI). /// </param> /// <param name="miso"> /// Master Input, Slave Output (MISO). /// </param> /// <param name="cs"> /// Chip Select pin. /// </param> public MCP3008(AdcChannels channel, IRaspiGpio spiclk, IRaspiGpio mosi, IRaspiGpio miso, IRaspiGpio cs) { this._channel = channel; this._clock = spiclk; this._clock.Provision(); this._masterOutSlaveIn = mosi; this._masterOutSlaveIn.Provision(); this._masterInSlaveOut = miso; this._masterInSlaveOut.Provision(); this._chipSelect = cs; this._chipSelect.Provision(); }
/// <summary> /// Initializes a new instance of the <see cref="CyrusBuilt.MonoPi.Devices.PiFace.PiFaceBase"/> /// class wtih the SPI channel and speed used to communicate with the PiFace. /// </summary> /// <param name="channel"> /// The SPI channel. /// </param> /// <param name="speed"> /// The SPI speed. /// </param> protected PiFaceBase(AdcChannels channel, Int32 speed) : base() { SimpleSPI.Init(channel, speed); this._inputPins = new IPiFaceGPIO[] { new PiFaceDigitalGPIO(PiFacePins.Input00, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input01, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input02, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input03, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input04, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input05, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Input06, PinState.Low) }; this._outputPins = new IPiFaceGPIO[] { new PiFaceDigitalGPIO(PiFacePins.Output00, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output01, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output02, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output03, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output04, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output05, PinState.Low), new PiFaceDigitalGPIO(PiFacePins.Output06, PinState.Low) }; this._relays = new IRelay[] { new RelayComponent(this._outputPins[0]), new RelayComponent(this._outputPins[1]) }; this._switches = new ISwitch[] { new SwitchComponent(this._inputPins[0]), new SwitchComponent(this._inputPins[1]), new SwitchComponent(this._inputPins[2]), new SwitchComponent(this._inputPins[3]) }; this._leds = new ILED[] { new LEDComponent(this._outputPins[0]), new LEDComponent(this._outputPins[1]), new LEDComponent(this._outputPins[2]), new LEDComponent(this._outputPins[3]), new LEDComponent(this._outputPins[4]), new LEDComponent(this._outputPins[5]), new LEDComponent(this._outputPins[6]), new LEDComponent(this._outputPins[7]) }; }
/// <summary> /// Write and read a block of data over the SPI bus. This is /// a full duplex operation. /// </summary> /// <returns> /// If successful, the data sent back in response; Otherwise, /// an empty string. /// </returns> /// <param name="channel"> /// The channel to transfer on. /// </param> /// <param name="data"> /// The data to transfer. /// </param> /// <exception cref="InvalidOperationException"> /// You initialize the SPI by calling Init() first. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// This module only supports a 2-channel device. Valid channels are /// <see cref="AdcChannels.Channel0"/> and <see cref="AdcChannels.Channel1"/>. /// </exception> public static String FullDuplexTransfer(AdcChannels channel, String data) { if (!_initialized) { throw new InvalidOperationException("SPI not yet initialized."); } if ((channel != AdcChannels.Channel0) && (channel != AdcChannels.Channel1)) { throw new ArgumentOutOfRangeException("Channel must be either either 0 or 1."); } Char[] buffer = data.ToCharArray(); if (UnsafeNativeMethods.wiringPiSPIDataRW((Int32)channel, buffer, buffer.Length) == -1) { return String.Empty; } return new String(buffer); }
/// <summary> /// Open the SPI device and set it up, etc. /// </summary> /// <param name="channel"> /// The channel to open. /// </param> /// <param name="speed"> /// The speed to negotiate the transfer rate at (ie. 38400). /// </param> public static Boolean Init(AdcChannels channel, Int32 speed) { if (_initialized) { return(true); } if ((channel == AdcChannels.Channel0) || (channel == AdcChannels.Channel1)) { _initialized = (UnsafeNativeMethods.wiringPiSPISetup((Int32)channel, speed) == 0); } else { _initialized = false; } return(_initialized); }
/// <summary> /// Write and read a block of data over the SPI bus. This is /// a full duplex operation. /// </summary> /// <returns> /// If successful, the data sent back in response; Otherwise, /// an empty string. /// </returns> /// <param name="channel"> /// The channel to transfer on. /// </param> /// <param name="data"> /// The data to transfer. /// </param> /// <exception cref="InvalidOperationException"> /// You initialize the SPI by calling Init() first. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// This module only supports a 2-channel device. Valid channels are /// <see cref="AdcChannels.Channel0"/> and <see cref="AdcChannels.Channel1"/>. /// </exception> public static String FullDuplexTransfer(AdcChannels channel, String data) { if (!_initialized) { throw new InvalidOperationException("SPI not yet initialized."); } if ((channel != AdcChannels.Channel0) && (channel != AdcChannels.Channel1)) { throw new ArgumentOutOfRangeException("Channel must be either either 0 or 1."); } Char[] buffer = data.ToCharArray(); if (UnsafeNativeMethods.wiringPiSPIDataRW((Int32)channel, buffer, buffer.Length) == -1) { return(String.Empty); } return(new String(buffer)); }
/// <summary> /// Write the specified data to the specified register on the specified /// channel. /// </summary> /// <param name="channel"> /// The channel to communicate with the target on. /// </param> /// <param name="register"> /// The register to write the data to. /// </param> /// <param name="data"> /// The data to write. /// </param> public static void Write(AdcChannels channel, Byte register, Byte data) { // Create packet in data buffer. Byte[] packet = new Byte[3]; packet[0] = (Byte)(DEFAULT_ADDRESS | WRITE_FLAG); packet[1] = register; packet[2] = data; // Convert the byte array into a char array to make wiringPiSPIDataRW happy. Char[] packetData = new Char[packet.Length]; for (Int32 i = 0; i <= (packetData.Length - 1); i++) { packetData[i] = (Char)packet[i]; } // Write the packet then clear both. UnsafeNativeMethods.wiringPiSPIDataRW((Int32)channel, packetData, packetData.Length); Array.Clear(packetData, 0, packetData.Length); Array.Clear(packet, 0, packet.Length); }
/// <summary> /// Reads a packet from the specified register over the specified channel. /// </summary> /// <param name="channel"> /// The channel to comunicate with the target on. /// </param> /// <param name="register"> /// The register to read the packet from. /// </param> /// <exception cref="IOException"> /// Failed to read from register. /// </exception> public static Byte Read(AdcChannels channel, Byte register) { Byte[] packet = new Byte[3]; packet[0] = (Byte)(DEFAULT_ADDRESS | READ_FLAG); packet[1] = register; packet[2] = 0x00; // We init null and then wiringPiSPIDataRW will assign. // Convert byte array to char array to make wiringPiSPIDataRW happy. Char[] packetData = new Char[packet.Length]; for (Int32 i = 0; i <= (packetData.Length - 1); i++) { packetData[i] = (Char)packet[i]; } Array.Clear(packet, 0, packet.Length); Int32 result = UnsafeNativeMethods.wiringPiSPIDataRW((Int32)channel, packetData, packetData.Length); if (result >= 0) { // Success. wiringPiSPIDataRW will have assigned the // the value read on the packet buffer. return (Byte)packet[2]; } String chstr = Enum.GetName(typeof(AdcChannels), channel); throw new IOException("Failed to read SPI bus on channel " + chstr, result); }
/// <summary> /// Open the SPI device and set it up, etc, at the default speed (1000000). /// </summary> /// <param name="channel"> /// The channel to open. /// </param> public static Boolean Init(AdcChannels channel) { return Init(channel, DEFAULT_SPEED); }
/// <summary> /// Initializes a new instance of the <see cref="CyrusBuilt.MonoPi.Devices.PiFace.PiFaceDevice"/> /// class wtih the SPI channel and speed used to communicate with the PiFace. /// </summary> /// <param name="channel"> /// The SPI channel. /// </param> /// <param name="speed"> /// The SPI speed. /// </param> public PiFaceDevice(AdcChannels channel, Int32 speed) : base(channel, speed) { }
/// <summary> /// Gets the file descriptor for the given channel. /// </summary> /// <returns> /// If successful, the file descriptor; Otherwise, -1. /// </returns> /// <param name="channel"> /// The channel to get the descriptor for. /// </param> public static Int32 GetFileDescriptor(AdcChannels channel) { Int32 descriptor = -1; if (_initialized) { if ((channel == AdcChannels.Channel0) || (channel == AdcChannels.Channel1)) { descriptor = UnsafeNativeMethods.wiringPiSPIGetFd((Int32)channel); } } return descriptor; }
/// <summary> /// Open the SPI device and set it up, etc, at the default speed (1000000). /// </summary> /// <param name="channel"> /// The channel to open. /// </param> public static Boolean Init(AdcChannels channel) { return(Init(channel, DEFAULT_SPEED)); }