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 07-May 23)


By content type

See this member's


Sort by                Order  

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

Posted by gbreder on 25 April 2012 - 08:05 AM in Beta Firmware and Drivers

In fact if I am debugging inside VS and pull teh USB cord our my computer instantly reboots... thats a nice feature.


Yeah,
this 'feature' is also discussed in Drivers for .NET MF 4.2.
There is an issue in Codeplex describing this behaviour. But sadly this bug can only be reproduced by another bug: Read on a disconnected I2C Bus takes forever.
This is not ideal. However you can try the repro and vote for it.
If something should be added or changed please send me a message.

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



#28237 SparkFun Inventor's Kit / CIRC-05 | 8 More LEDs - 74HC595 Shift Register

Posted by gbreder on 27 April 2012 - 10:55 PM in Netduino Go

Hi Gutworks,
a singleton can work until you add your second shield base. If you will never ever do this you code is fine.

A singelton if often used if the following is true:
  • Your class can only be instantiated once, there may not be a second instance of the class (like I2C bus on the classic Neduino).
  • Your class will be used in multiple other classes in your code.
  • You have no idea which code will call your class when. And so you have no idea who has to call the contructor.
Without the singleton pattern you would have to build the instance yourself (call the contructor) and give it to every class which may need it. This can get very ugly...

The use of an normal contructor (as stated in my earlier post) would suffice because your program calls "GetInstanc" once, your singleton will be used in only one class and you know when to call the constructor.

It isn't my intention to be rude and I'm absolutly thrilled that you have coded a beautiful singleton pattern. But simpler may be better.

Regards
Guido



#28165 SparkFun Inventor's Kit / CIRC-05 | 8 More LEDs - 74HC595 Shift Register

Posted by gbreder on 26 April 2012 - 07:15 PM in Netduino Go

Hi,
the static contructor is a solution but I prefer a diffrent approach. My main program always looks like this:
using System.Threading;

namespace Netduino.Extender
{
	public class Program
	{
		private static ImportantController _ImportantController;
		
		public static void Main()
		{
			_ImportantController = new ImportantController();
			Thread.Sleep(Timeout.Infinite);
		}
	}
}
Now I'm done with all the static stuff. The real party starts in my "ImportantController" (in real life the class name is not "ImportantController" of course).
using ...;

namespace Netduino.Extender.Heating
{
	public class ImportantController 
	{
		private readonly Lcd _Lcd;
		private readonly SwitchModule _SwitchModule;
		
		public ImportantController()
		{
			ILcdTransferProvider lcdTransportProvider = new Shifter74Hc595LcdTransferProvider(...);
			_Lcd = new Lcd(lcdTransportProvider, ...);
			_SwitchModule = new SwitchModule(...);
			_SwitchModule.ItemChanged += SwitchModuleItemChanged;
		}
		...
		void SwitchModuleItemChanged()
		{
			_Lcd.Write();
			...
		}
	}
}

In my opinion the advantage is that only one class (the "ImportantController") must be declared static. Inside this class you can decide if the objects should be instanciated more than once or if it should be static for some reason. Also if you want to refactor your code you don't have to remove all "static" modifiers. For example if you build a class with a field to count something and you need this class a second time the field shouldn't be static because your counter would count the "somethings" of all your instances.
Maybe the code in my example is a little bit desktop style programming but I don't know a reason against my approach. If there is one I would be happy to know it.

Sorry for the short and confused explanation but I've cought a cold and my brain is alread in bed sleeping :-)

Regards
Guido



#28253 SparkFun Inventor's Kit / CIRC-05 | 8 More LEDs - 74HC595 Shift Register

Posted by gbreder on 28 April 2012 - 09:26 AM in Netduino Go

Hi,
I'm happy to help. I've mode some major and some minor changes. All major changes are listed below. The whole result was zipped and attached. But be aware that my Netduino GO hasn't arrived yet. So the code is completely untested.

  • The "controller" isn't nested anymore. A nested type is only used if it is related to its parent in some way.
  • The method "UpdateLeds" was moved inside "ShieldBaseController" because it was accessing only OutputPorts from it.
  • All output ports are now private.
  • The statement "bits[led]" and its "bits" array was replaced by a bit shift operation "1 << led".
  • The "mask[led]" was also expressed as (inverted) bit shift "~(1<<led)". For example 1<<4 would result in 16 (or 0x10) and the "~" will invert every bit in the byte so you will get 0xEF or 239. Less manual calculations and less code results in less errors :-)
  • Some minor renaming and other unimportant stuff

There is still room for improvement. You could change your SPI bit bang mode to native SPI from the Netduino. I've attached a class for the 74HC595 from my classic Netduino as example. You can also provide the parameter "GoSockets.Socket5" for your "new ShieldBase()" through the constructor of the class.

Regards
Guido



#28255 SparkFun Inventor's Kit / CIRC-05 | 8 More LEDs - 74HC595 Shift Register

Posted by gbreder on 28 April 2012 - 09:30 AM in Netduino Go

The whole result was zipped and attached.

Forgot to press the "Attach This File" button ;)

Attached Files




#28749 SparkFun Inventor's Kit / CIRC-05 | 8 More LEDs - 74HC595 Shift Register

Posted by gbreder on 09 May 2012 - 08:23 PM in Netduino Go

How would you get two shift registers working?

You would put the second shift register also on SPI1 and define a different latch pin (aka slave select / device select).

If it is a 74HC595 shifter you can use something like this:
public class Shifter74Hc595Extender
{
	public Shifter74Hc595Extender(SPI.SPI_module spiBus, Cpu.Pin latchPin)
	{
		var spiConfig = new SPI.Configuration(
			latchPin, //latchPin (aka SlaveSelect),
			false, // active state
			0, // setup time
			0, // hold time 
			false, // clock idle state
			true, // clock edge
			1000, // clock rate
			spiBus);

		_Spi = new SPI(spiConfig);	
	}

	public void WriteData(byte data)
	{
		_WriteBuf[0] = data;
		_Spi.Write(_WriteBuf);
	}
}
I hope this helps...

Regards
Guido



#27840 Power consumption / limits

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

Hi, I would get a capacitor with a higher voltage. Something like 50V to 60V. If the TSR-1 needs 22uF you should get exactly the 22uF. If you need 1000uF for the rectifier you should get one and put them both in parallel. But I would put the rectifier capacitor near the rectifier and the TSR cap near the TSR. This should give the best result. Capacitor theory (oversimplified): Small caps can filter very small ripple (but not huge ripple) because they take little time to load and unload. Huge caps can filter huge ripple (but not small ripple) because it takes a long time to load and unload. Regards Guido



#27524 Power consumption / limits

Posted by gbreder on 18 April 2012 - 08:15 AM in Netduino Plus 2 (and Netduino Plus 1)

Hi,
the really hot resistor is a possible way but I wouldn't recommend it. I've build a switching power supply my self (based on the LM2596, but they are also available fully assembled.

For example the TSR1 module is very easy to use: One Pin is Vin, one is Ground and the last puts out your 5V. And this goes up to 2.5Amps 1Amp without a heatsink.

Regards
Guido

P.S.: Paul pointed out that the maximum power output is 1A instead of 2.5A. Thanks.



#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



#27909 Power consumption / limits

Posted by gbreder on 22 April 2012 - 10:25 PM in Netduino Plus 2 (and Netduino Plus 1)

Hi, the low resistance of the tantalum caps tends to set them on fire if they are loaded and then short-circuited or if the caps grow old or something unexpected happens to you circuit... This is a fact you should be aware of. My recommendation is to avoid tantalum but on the other side it is recommended by the vendor because the circuit is designed for tantalum caps and it would provide the best result. On most designs I would put normal caps in the circuit and I would check if the result is good enough. (This reminds me to buy a scope :) ) Guido



#27856 Drivers for .NET MF 4.2

Posted by gbreder on 21 April 2012 - 09:38 PM in Beta Firmware and Drivers

Hi,
at last I've posted the issue in Codeplex. Everyone should try the repro and vote for it. :)
If something should be added or changed please send me a message.

Guido

P.S. There is another bug I'm interrested in: Read on a disconnected I2C Bus takes forever. The foundation of the bluescreen repro is this bug. Everyone can also try the repro, vote for it, send me his or her results (with board type and firmware) and of course his or her opinion...

Guido



#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



#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




#37052 simple wiring question

Posted by gbreder on 11 October 2012 - 08:05 PM in Netduino 2 (and Netduino 1)

Hi perkunas.
The connection "P2" will sense a low signal when the switch is closed. The resistor at the +5V and the switch at the bottom will form a voltage divider. The calculation is fairly easy because the switches resistance is (nearly) 0 ohm if closed and (nearly) infinite ohm if opened.
Closed: 5V * (0/(10000 + 0) = 0
see Wikipedia Voltage divider

The resistor at P2 is not relevant for the calculation.

Regards
Guido



#28106 Industrial Use Case

Posted by gbreder on 25 April 2012 - 09:46 PM in General Discussion

Hi, to stress Marios point a littel bit more I can tell my own story: One of my Netduino boards controls my heating. It receives all temperature data then processes it and after that controls all heating valves (they are in one place). The whole application is event driven and if I use the firmware 4.1.1beta it runs week after week. So far so good. But if I update to firmware to 4.2 RC3/RC4 the same application hangs without an exception after 6 to 12 hours. This is a little bit anoying. But the most anoying thing is that I can't reproduce the bug in a manner of: "I do something and the board gets stuck." Don't get me wrong: I think Netduino is by far one of the best Micro Framework boards out there but I would'nt do anyting mission critical with it too. Regards Guido



#27853 PC rebooting on NetduinoPlus Disconnect

Posted by gbreder on 21 April 2012 - 09:31 PM in Beta Firmware and Drivers

Hi smarcus,
at last I've posted the issue in Codeplex.
Please vote for it. If something should be added or changed please send me a message.

Guido

P.S. There is another bug I'm interrested in: Read on a disconnected I2C Bus takes forever. If you like, try the repro and send me your result (with your board and firmware) and of course your opinion :)



#27794 PC rebooting on NetduinoPlus Disconnect

Posted by gbreder on 21 April 2012 - 08:33 AM in Beta Firmware and Drivers

Hi,
there is already another thread which decribes this behaviour.
There is no fix but repro steps in there: Drivers for .NET MF 4.2

Ok, I'm not really helping here. But I'm frustrated by BSOD too and I'm unsure what to do.
Should I open a bug in Codeplex? :unsure: I've posted the repro but in the last week there was no response.

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



#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



#27626 Multiple I2C devices

Posted by gbreder on 19 April 2012 - 07:38 AM in Netduino 2 (and Netduino 1)

Hi teo, I will try your code at a later time but in the meantime please answer me: which Netduino firmware are you running? Guido P.S: I've tested your code. Works well on firmware 4.2.0.0 RC4. I have none of your devices of course but the exception should occur without them...



#27764 Multiple I2C devices

Posted by gbreder on 20 April 2012 - 10:28 PM in Netduino 2 (and Netduino 1)

Hi teo,
most possibly your firmware is something like 4.0.6 or so.
A good firmware for repeated start bit support is Version: 4.1.1 BETA 1 (version 4.1.1.0 b1)
You have to update the tiny booter decrompressor too. A superb how to is in the wiki.
After that you can update the firmware of your Netduino.

Version 4.1.1.0 b1 is really stable. My under floor heating runs on 4.1.1.0 b1 till january. The 4.2.0.0 will be great too but until now the same program gets stuck after 6 to 12 hours if it runs on 4.2.

Regards
Guido



#27791 Multiple I2C devices

Posted by gbreder on 21 April 2012 - 07:39 AM in Netduino 2 (and Netduino 1)

Hi teo,
without the data sheet of the gyro I would guess something like that:
device.ReadInternalAddressBytes(i2cconf2, rbuf, 27, 1);
because the fourth parameter is the count of bytes that are used for the internal address and your internal address fits nicely in on byte.
But only the data sheet of your gyro sensor can answer your question.

Guido



#46918 Connecting the Shield Base Module to run alone

Posted by gbreder on 08 March 2013 - 10:40 PM in Netduino Go

Hi Chris,

Thanks for your quick reply.

I've
converted the original DFU file of the Netduino 2 Firmware (v4.3.0.0
Beta1) to a S19 file. Then I was able to deploy the converted file via
the Flash Loader to the shield base. The settings were default (115200
boud, even parity, echo disabled, timeout 10s).

 

Now I've hit a wall. How do I deploy an application to my shield base? The N2 accepts data from the USB but on the shieldbase the pins PA11 and PA12 (which are used for USB on the N2) are pulled high to 3V3.

 

Do I deploy the application through Digital I/O 0 and 1 or through the GoSocket? On Stefans firmware the application will be deployed through the GoPort. Nice, you can use the same connection as for flashing the firmware

 

And is there a tutorial to build a firmware with a custom deployment mode? Ah I've found the firmware tutorial: http://wiki.netduino...-6.ashx?HL=base

 

Do I have to build my own firmware from the sources? My converted firmware does obviously neither support dedicated I2C because the pins are not connected nor does it allow an deployment because it expects data on PA11/PA12.

 

Thanks again

Guido




#46854 Connecting the Shield Base Module to run alone

Posted by gbreder on 07 March 2013 - 10:41 PM in Netduino Go

Hi Stefan,

after I read the post nearly a year ago I immediately bought two extra shieldbases for my Netduino Go. They were both very busy gathering dust since then. A few days ago i tried your shieldbase hacking with my FTDI adapter board. No success with the connection. There are a few question I would like to ask:

  • What are the correct settings in the Flash Loader: baud, parity, echo, timeout?
  • Must the reset "button" be released after power up? Do I have to pull the jumper wire which pulls reset to 3V3 before connecting with Flash Loader?
  • What are the differences between the file formats ".s19", ".dfu" and the embedded resources of the normal shield base update solution for Visual Studio
  • Can I convert a firmware file from one format to another?
  • Is the new Netduino 2 firmware compatible to the shield base? The MCU is the same and there is the schematic of the Netduino 2 but I haven't found any Schematics for the shieldbase. :(
  • Can a ".dfu" file be deployed to the shieldbase.

Thanks in advance for your help.

 

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.