Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

gbreder's Content

There have been 35 items by gbreder (Search limited from 18-May 23)


By content type

See this member's


Sort by                Order  

#27396 Use MAX521 DAC with i2c

Posted by gbreder on 16 April 2012 - 07:34 PM in Netduino Plus 2 (and Netduino Plus 1)

Hi,
the Arduino code
Wire.send((B00000111 & port)); //use some BitWise "&" to combine the command to write to a port with the port you wish to write to
Wire.send(value); //send the actual value to the port
would translate to
I2CBus.GetInstance().Write(_slaveConfig, new byte[] { (byte)(0x07 & port) }, TransactionTimeout);
I2CBus.GetInstance().Write(_slaveConfig, new byte[] { 0xFF }, TransactionTimeout);
where "port" is 0x00 for DAC0.

Maybe this will work :)

Regard
Guido



#27395 Power consumption / limits

Posted by gbreder on 16 April 2012 - 07:20 PM in Netduino Plus 2 (and Netduino Plus 1)

Hi, Paul has quoted the relevant specification and a really important sentence: "...at 12V, over half of the power consumed by the Netduino will be wasted as heat..." The power regulator will transform everything above 5 volts to heat. If you power your board with 6 volts and you draw a current of 200mA there is about ((6-5)*0.2) 0.2W of "heat". If you power your board with 15V and you draw 200mA there is about ((15-5)*0.2) 2.0W of "heat". This is a lot because the regulator has nearly no heatsink. The calculation may be a bit oversimplified but you will get the idea. Somewhere on the forum I read a nice rule of thumb: If you can't touch the regulator with you finger (because it's to hot) rethink your power supply design. Regards Guido



#27389 Use MAX521 DAC with i2c

Posted by gbreder on 16 April 2012 - 06:16 PM in Netduino Plus 2 (and Netduino Plus 1)

Hi, the first common mistake of I2C devices is to take all eight bits of the address. Please take only the most significant 7 and shift them one place to the right. The datasheet says that the address is someting like: 0, 1, 0, 1, ADR2, ADR1, ADR0, R/W This results in addresses between: 0x28 and 0x2F (these address values are hexadecimal) Is your address in this range? The first write statement writes zero to DAC7. Is this right? What should the second write statement do? Regards Guido



#27231 Drivers for .NET MF 4.2

Posted by gbreder on 14 April 2012 - 07:49 AM in Beta Firmware and Drivers

Hello Chris, I've rebooted my computer by Netduino reset several times. To reproduce the error the step "Slowly count to ten" has to be inserted between "Hit deploy in VS" and "Press reset button on Netduino". I've attached the solution with the I2C issue and my "msinfo32" system information to show my hardware and installed drivers. (In case you need to by a computer to reproduce the error... :) ) I hope this helps. If you need further information feel free to contact me. Regards Guido

Attached Files




#27182 Drivers for .NET MF 4.2

Posted by gbreder on 13 April 2012 - 08:23 PM in Beta Firmware and Drivers

Hi Chris,
I've one repro for two bugs. I've written a small program:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace I2CIssue
{
public class Program
{
	private static I2CDevice _I2CDevice;
	private static Timer _Timer;
	private static OutputPort _OnboardLed;

	public static void Main()
	{
		_Timer = new Timer(TimerElapsed, null, new TimeSpan(0, 0, 15), new TimeSpan(0, 0, 15));

		//Initialize the I2CDevice with a dummy configuration
		_I2CDevice = new I2CDevice(new I2CDevice.Configuration(20, 100));
		_OnboardLed = new OutputPort(Pins.ONBOARD_LED, false);

		Thread.Sleep(Timeout.Infinite);
			
	}

	private static void TimerElapsed(object state)
	{
		var bytesToRead = new byte[2];

		var configuration = new I2CDevice.Configuration(0x48, 100);
		_I2CDevice.Config = configuration;

		var transactions = new[] { I2CDevice.CreateReadTransaction(bytesToRead) };

		_OnboardLed.Write(true);
		Thread.Sleep(50);
		_OnboardLed.Write(false);

		Debug.Print("Beginning read on disconnected I2C bus...");
		// Execute the read or write transaction, check if byte was successfully transfered
		int bytesTransfered = _I2CDevice.Execute(transactions, 200);

		Debug.Print("Bytes transferred '" + bytesTransfered + "' at " + DateTime.Now);
	}
}
}

This code should try a read on a disconnected I2C bus. All pullups have to be removed as well. After 200ms the read should be aborted with an exception or an result of zero byte or something (_I2CDevice.Execute(transactions, 200)). But on Firmware 4.2 RC4 the Netduino stops completetly. Now you should try a deploy to such an unresponsive board. And while Visual Studio is desperately trying to deploy the application to the unresponsive Netduino, hit the reset button on the board. Your computer will reboot immediately.

I hope my repro steps can be reproduced by others. :)

Regards
Guido



#27144 Multiple I2C devices

Posted by gbreder on 13 April 2012 - 08:05 AM in Netduino 2 (and Netduino 1)

Hi teo,
the most important thing is that the class will be used like this:
I2CAdapter adapter = I2CAdapter.Instance;
adapter.WriteBytes(...);
instead of something like that:
Picture picture = new Picture();
picture.Load(...);

Regards
Guido



#27095 Casting Pins Exception

Posted by gbreder on 12 April 2012 - 07:51 PM in Netduino Plus 2 (and Netduino Plus 1)

Hi, the "SecretLabs.NETMF.Hardware.Netduino.Pins" are in fact only constants with "Microsoft.SPOT.Hardware.Cpu.Pin" definitions inside. They exist only for one purpose: to give them a cool name like "Pins.GPIO_PIN_D7" instead of "Pin.GPIO_Pin3". Both names decribe the digital port 7. Only "...D7" is easier to remember than "3". There is no cast involved and each parameter in a method signature has to use "Microsoft.SPOT.Hardware.Cpu.Pin". If you use your VisualStudios IntelliSense feature on a Netduin pin definition (hover over it with your mouse) you see the Microsoft pin definition in the popup text. Regards Guido



#27093 Multiple I2C devices

Posted by gbreder on 12 April 2012 - 07:18 PM in Netduino 2 (and Netduino 1)

Hi,
a class like the following will most possibly fit your requirement:

using System;
using System.Reflection;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace Netduino.Extender.TransferAdapters
{
	/// <summary>
	/// Wire-up the I2C device to the Netduino as follows:
	/// SDA -> Analog Pin 4;
	/// SCL -> Analog Pin 5;
	/// GND -> GND.
	/// </summary>
	public sealed class I2CAdapter
	{
		private static readonly Object _I2CLock = new object();
		private static readonly I2CAdapter _Instance = new I2CAdapter();

		private readonly I2CDevice _I2CDevice;

		/// <summary>Creates a new <see cref="I2CAdapter"/> instance </summary>
		/// <remarks>
		/// At this time the .NET Micro Framework only supports a single I2C bus. 
		/// Therefore, creating more than one I2CAdapter instance will generate an
		/// exception. 
		/// </remarks>
		private I2CAdapter()
		{
			//Initialize the I2CDevice with a dummy configuration
			_I2CDevice = new I2CDevice(new I2CDevice.Configuration(0, 0));
		}

		public static I2CAdapter Instance
		{
			get { return _Instance; }
		}

		private I2CDevice.I2CWriteTransaction CreateInternalAddressWriteTransaction(byte[] buffer, uint internalAddress,
		                                                                            byte internalAddressSize)
		{
			I2CDevice.I2CWriteTransaction writeTransaction = I2CDevice.CreateWriteTransaction(buffer);

			ModifyToRepeatedStartTransaction(internalAddress, internalAddressSize, writeTransaction,
			                                 typeof (I2CDevice.I2CWriteTransaction));

			return writeTransaction;
		}

		private I2CDevice.I2CReadTransaction CreateInternalAddressReadTransaction(byte[] buffer, uint internalAddress,
		                                                                          byte internalAddressSize)
		{
			I2CDevice.I2CReadTransaction readTransaction = I2CDevice.CreateReadTransaction(buffer);

			ModifyToRepeatedStartTransaction(internalAddress, internalAddressSize, readTransaction,
			                                 typeof (I2CDevice.I2CReadTransaction));

			return readTransaction;
		}

		/// <summary>
		/// To use the new I2C InternalAddress feature (repeated start bit) in the v4.1.1 alpha,
		/// add the following method to your code...
		/// and then call it instead of built-in I2CDevice.CreateWriteTransaction/CreateReadTransaction functions when appropriate.
		/// </summary>
		/// <param name="internalAddress"></param>
		/// <param name="internalAddressSize">The InternalAddressSize parameter defines
		/// the # of bytes used to represent the InternalAddress. The InternalAddress is a set of bytes sent to a device before the
		/// buffer--often a register # or memory location to write/read. When used in an I2C ReadTransaction, an extra start bit will
		/// be sent to the I2C device after the InternalAddress (followed by the traditional buffer read/write).</param>
		/// <param name="transaction"></param>
		/// <param name="transactionType"></param>
		private static void ModifyToRepeatedStartTransaction(uint internalAddress, byte internalAddressSize,
		                                                     I2CDevice.I2CTransaction transaction, Type transactionType)
		{
			FieldInfo fieldInfo = transactionType.GetField("Custom_InternalAddress",
			                                               BindingFlags.NonPublic | BindingFlags.Instance);
			fieldInfo.SetValue(transaction, internalAddress);

			fieldInfo = transactionType.GetField("Custom_InternalAddressSize", BindingFlags.NonPublic | BindingFlags.Instance);
			fieldInfo.SetValue(transaction, internalAddressSize);
		}

		public int WriteInternalAddressBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToWrite,
		                                     uint internalAddress, byte internalAddressSize)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration,
			                                             CreateInternalAddressWriteTransaction(bytesToWrite, internalAddress,
			                                                                                   internalAddressSize));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToWrite.Length))
			{
				Debug.Print("WriteInternalAddressBytes: I2C expected + '" + bytesToWrite.Length + "' but could write + '" +
				            bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int ReadInternalAddressBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToRead, uint internalAddress,
		                                    byte internalAddressSize)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration,
			                                             CreateInternalAddressReadTransaction(bytesToRead, internalAddress,
			                                                                                  internalAddressSize));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToRead.Length))
			{
				Debug.Print("ReadInternalAddressBytes: I2C expected + '" + bytesToRead.Length + "' but could read + '" +
				            bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int WriteBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToWrite)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration, I2CDevice.CreateWriteTransaction(bytesToWrite));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToWrite.Length))
			{
				Debug.Print("WriteBytes: I2C expected + '" + bytesToWrite.Length + "' but could write + '" + bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int ReadBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToRead)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration, I2CDevice.CreateReadTransaction(bytesToRead));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToRead.Length))
			{
				Debug.Print("ReadBytes: I2C expected + '" + bytesToRead.Length + "' but could read + '" + bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="configuration">Netduino needs only the 7 most significant bits for the address e.g. 0x91 >> 1 = 0x48.</param>
		/// <param name="transaction"></param>
		/// <returns></returns>
		private int ExecuteI2CTransactions(I2CDevice.Configuration configuration, I2CDevice.I2CTransaction transaction)
		{
			lock (_I2CLock)
			{
				_I2CDevice.Config = configuration;

				// Execute the read or write transaction, check if byte was successfully transfered
				int bytesTransfered = _I2CDevice.Execute(new[] {transaction}, 100);
				return bytesTransfered;
			}
		}
	}
}
This class takes a I2CDevice.Configuration for each read and write and can be used multiple times for diffrent devices. It should be tread-safe. To get an instance of this class please call "I2CAdapter.Instance" (singleton pattern). The Read/WriteInternalAddressBytes methods are used in Firmware 4.1.1 beta 1 and 4.2.0 RCx. They won't work in 4.0. If there are errors in my code or if there are suggestions for improvement please let me know.
Now you should be able to use the one I2C bus of your Netduino with ease for diffrent devices.

Regards
Guido



#26772 First Project Idea - Rotating Plant Stand

Posted by gbreder on 09 April 2012 - 12:40 PM in General Discussion

Hi Jackie,
the answer is: it depends...
My first real project after blinking a LED was to automate my floor heating system. It took about one year (and several hundreds of dollars) and now I have a wireless heating controlled by Netduino. Feels fantastic!

Your project seems makable, but you should define you project requirements first.
  • On what is the rotation speed depending?
  • How does your plant stand detect obstacles (like cats)?
  • ...

If all your requirements are defined you can divide your project into smaller projects (one for each requirement) and combine them later to the end result. If this project is a good start depends on your patience and if you can handle several small projects.

Regards
Guido



#25527 Netduino Firmware v4.2.0 RC4 (Netduino + Netduino Plus)

Posted by gbreder on 14 March 2012 - 10:28 PM in Beta Firmware and Drivers

Hi Rohan,
to get your I2C bus working you can use a class like this:

using System;
using System.Reflection;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace Netduino.Extender.TransferAdapters
{
	/// <summary>
	/// Wire-up the I2C device to the Netduino as follows:
	/// SDA -> Analog Pin 4;
	/// SCL -> Analog Pin 5;
	/// GND -> GND.
	/// </summary>
	public sealed class I2CAdapter
	{
		private static readonly Object _I2CLock = new object();
		private static readonly I2CAdapter _Instance = new I2CAdapter();

		private readonly I2CDevice _I2CDevice;

		/// <summary>Creates a new <see cref="I2CAdapter"/> instance </summary>
		/// <remarks>
		/// At this time the .NET Micro Framework only supports a single I2C bus. 
		/// Therefore, creating more than one I2CAdapter instance will generate an
		/// exception. 
		/// </remarks>
		private I2CAdapter()
		{
			//Initialize the I2CDevice with a dummy configuration
			_I2CDevice = new I2CDevice(new I2CDevice.Configuration(0, 0));
		}

		public static I2CAdapter Instance
		{
			get { return _Instance; }
		}

		private I2CDevice.I2CWriteTransaction CreateInternalAddressWriteTransaction(byte[] buffer, uint internalAddress,
		                                                                            byte internalAddressSize)
		{
			I2CDevice.I2CWriteTransaction writeTransaction = I2CDevice.CreateWriteTransaction(buffer);

			ModifyToRepeatedStartTransaction(internalAddress, internalAddressSize, writeTransaction,
			                                 typeof (I2CDevice.I2CWriteTransaction));

			return writeTransaction;
		}

		private I2CDevice.I2CReadTransaction CreateInternalAddressReadTransaction(byte[] buffer, uint internalAddress,
		                                                                          byte internalAddressSize)
		{
			I2CDevice.I2CReadTransaction readTransaction = I2CDevice.CreateReadTransaction(buffer);

			ModifyToRepeatedStartTransaction(internalAddress, internalAddressSize, readTransaction,
			                                 typeof (I2CDevice.I2CReadTransaction));

			return readTransaction;
		}

		/// <summary>
		/// To use the new I2C InternalAddress feature (repeated start bit) in the v4.1.1 alpha,
		/// add the following method to your code...
		/// and then call it instead of built-in I2CDevice.CreateWriteTransaction/CreateReadTransaction functions when appropriate.
		/// </summary>
		/// <param name="internalAddress"></param>
		/// <param name="internalAddressSize">The InternalAddressSize parameter defines
		/// the # of bytes used to represent the InternalAddress. The InternalAddress is a set of bytes sent to a device before the
		/// buffer--often a register # or memory location to write/read. When used in an I2C ReadTransaction, an extra start bit will
		/// be sent to the I2C device after the InternalAddress (followed by the traditional buffer read/write).</param>
		/// <param name="transaction"></param>
		/// <param name="transactionType"></param>
		private static void ModifyToRepeatedStartTransaction(uint internalAddress, byte internalAddressSize,
		                                                     I2CDevice.I2CTransaction transaction, Type transactionType)
		{
			FieldInfo fieldInfo = transactionType.GetField("Custom_InternalAddress",
			                                               BindingFlags.NonPublic | BindingFlags.Instance);
			fieldInfo.SetValue(transaction, internalAddress);

			fieldInfo = transactionType.GetField("Custom_InternalAddressSize", BindingFlags.NonPublic | BindingFlags.Instance);
			fieldInfo.SetValue(transaction, internalAddressSize);
		}

		public int WriteInternalAddressBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToWrite,
		                                     uint internalAddress, byte internalAddressSize)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration,
			                                             CreateInternalAddressWriteTransaction(bytesToWrite, internalAddress,
			                                                                                   internalAddressSize));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToWrite.Length))
			{
				Debug.Print("WriteInternalAddressBytes: I2C expected + '" + bytesToWrite.Length + "' but could write + '" +
				            bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int ReadInternalAddressBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToRead, uint internalAddress,
		                                    byte internalAddressSize)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration,
			                                             CreateInternalAddressReadTransaction(bytesToRead, internalAddress,
			                                                                                  internalAddressSize));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToRead.Length))
			{
				Debug.Print("ReadInternalAddressBytes: I2C expected + '" + bytesToRead.Length + "' but could read + '" +
				            bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int WriteBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToWrite)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration, I2CDevice.CreateWriteTransaction(bytesToWrite));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToWrite.Length))
			{
				Debug.Print("WriteBytes: I2C expected + '" + bytesToWrite.Length + "' but could write + '" + bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		public int ReadBytes(I2CDevice.Configuration i2CConfiguration, byte[] bytesToRead)
		{
			int bytesTransfered = ExecuteI2CTransactions(i2CConfiguration, I2CDevice.CreateReadTransaction(bytesToRead));

			// I2CDevice.Execute returns the total number of bytes transfered in BOTH directions for all transactions
			if (bytesTransfered < (bytesToRead.Length))
			{
				Debug.Print("ReadBytes: I2C expected + '" + bytesToRead.Length + "' but could read + '" + bytesTransfered + "'.");
			}

			return bytesTransfered;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="configuration">Netduino needs only the 7 most significant bits for the address e.g. 0x91 >> 1 = 0x48.</param>
		/// <param name="transaction"></param>
		/// <returns></returns>
		private int ExecuteI2CTransactions(I2CDevice.Configuration configuration, I2CDevice.I2CTransaction transaction)
		{
			lock (_I2CLock)
			{
				_I2CDevice.Config = configuration;

				// Execute the read or write transaction, check if byte was successfully transfered
				int bytesTransfered = _I2CDevice.Execute(new[] {transaction}, 100);
				return bytesTransfered;
			}
		}
	}
}
This class takes a I2CDevice.Configuration for each read and write and can be used multiple times for diffrent devices. It should be tread-safe. To get an instance of this class please call "I2CAdapter.Instance" (singleton pattern). The Read/WriteInternalAddressBytes methods are used in Firmware 4.1.1 beta 1. The rest of the code works brillint in 4.2.x. If there are errors in my code or if there are suggestions for improvement please let me know.
Now you should be able to use the one I2C bus of your Netduino with ease for diffrent devices.

Regards
Guido




home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.