Netduino home hardware projects downloads community

Jump to content


NameOfTheDragon

Member Since 27 Feb 2014
Offline Last Active Feb 16 2017 07:48 PM
-----

#64333 Netduino.IP Firmware v1.0.1 (for Netduino Plus 2)

Posted by NameOfTheDragon on 19 October 2015 - 04:23 PM

There's reporting and there's reporting. I can't find your reports in the forums anywhere. If you are certain you've found a bug, I would suggest opening an issue against the GitHub repository, as I did with the DHCP issues. Before doing that though, you need to be pretty sure of your facts and have a method to reproduce the problem.

 

I've found the sockets interface to be pretty obscure and it's not obvious how things are supposed to work a lot of the time. I've been using Socket.Poll in my own code and it seems to work OK, but it took a lot of digging to work out how to do what I wanted. It might be an idea to post your non-working code and ask for people to suggest why it might not be working before assuming its a bug.

 

--Tim




#64328 Netduino.IP Firmware v1.0.1 (for Netduino Plus 2)

Posted by NameOfTheDragon on 18 October 2015 - 05:55 PM

As a workaround to the above issue, in MFDeploy, select the option to Use the following DNS server addresses, then set both servers to 0.0.0.0. The network stack will then see that you haven't specified any DNS servers and will fall back to using the ones obtained from DHCP.

 

Note that the IP address must have also been obtained from DHCP for this to work. The NetworkInterface.DnsAddresses property will return an empty array, so you will not be able to determine the server addresses in code.

 

Currently, as of Netduino.IP 1.0.1, any attempt to use Obtain DNS server addresses automatically in MFDeploy will cause your code to fail and will throw a NullReferenceException if you attempt to read the NetworkInterface.DnsAddresses property.

 

Clearly, something is still very broken here.




#63778 PWM

Posted by NameOfTheDragon on 05 August 2015 - 07:46 PM

As MArk said, PWM timers are inherently free-running so there's not really a reliable way to stop them after one cycle. The CPU on the Netduino has lots of timers that might be able to set an output when they time out, but I'm not sure if the .Net Framework provides direct access to those. Depending on how critical your timing is, you might be able to do it with a CLR timer (System.Threading.Timer), which have a resolution of 1 millisecond which happens to be about what you want, but keep in mind that 'Windows' has never been considered to be a deterministic operating system so the call back might not happen on time.

 

Without knowing what you're trying to achieve (the XY problem http://xyproblem.info)then it seems like the solution is to use some sort of external device, a 555 timer or an RC circuit that you can trigger from an output.

 

Regards,

Tim Long 




#63626 SerialPort Receive Data Corruption

Posted by NameOfTheDragon on 23 July 2015 - 12:32 PM

Hawkez, I replied to your issue on codeplex.

 

For what it's worth, I have had good results using COM1, with a device that doesn't support flow control, at 9600 baud. I think the trick is that you have to service the DataReceived event as quickly as possible and not introduce any unnecessary delay. The serial port raises the event sometimes for every character so you have to service it really quickly - at 9600 you've only got about a millisecond (104 microseconds) before the next event could arrive.

 

My event handler looks like this:

        void HandleDataReceivedEvent(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
            {
            if (serialDataReceivedEventArgs.EventType == SerialData.Eof)
                {
                Dbg.Trace("SerialData.Eof event - ignoring", Source.SerialPort);
                return;
                }
            try
                {
                lock (receiveBuffer)
                    {
                    var bytesToRead = serialPort.BytesToRead;
                    if (bytesToRead < 1) 
                        return;
                    var bufferAvailable = bufferSize - bufferHead;
                    if (bytesToRead > bufferAvailable)
                        throw new IOException("Serial read buffer overflow. Consider increasing the buffer size");
                    var bytesReceived = serialPort.Read(receiveBuffer, bufferHead, bufferAvailable);
                    bufferHead += bytesReceived;
                    Dbg.Trace("Received " + bytesReceived + " bytes, " + bufferHead + " bytes in buffer",
                        Source.SerialPort);
                    }
                dataReceivedSignal.Set();
                }
            catch (Exception ex)
                {
                Dbg.Trace("Exception handling DataReceivedEvent: "+ex.Message, Source.SerialPort);
                }
            }

dataReceivedSignal is a ManualResetEvent; Dbg.Trace() is essentially a wrapper around Debug.Print() - and yes the code works, even with a Debug.Print in there.

 

When it comes to getting the data out of the buffer, I do it like this (this happens on a different thread, which is why I need to lock the buffer):

        /// <summary>
        ///     Receives raw bytes from the console up to the maximum specified, optionally skipping bytes from the start,
        ///     until no data is received fro the specified quiet time.
        /// </summary>
        /// <param name="bytesToReceive">
        ///     The number of bytes to receive from the serial port, including any skipped
        ///     bytes. Additional data received by the serial port will be discarded.
        /// </param>
        /// <param name="timeout">
        ///     The timeout period, after which an exception is thrown if the required number of bytes
        ///     have not been received.
        /// </param>
        /// <param name="skipBytes">
        ///     The number of bytes to be dropped from the front of the received data. Optional;
        ///     default is 0.
        /// </param>
        /// <returns>
        ///     System.Byte[] containing the received data. The size of this array will be
        ///     <paramref name="bytesToReceive" /> - <paramref name="skipBytes" />.
        /// </returns>
        /// <exception cref="SerialReadTimeoutException">
        ///     Timed out while waiting for  + maxBytesToCopy.ToString() +
        ///     bytes
        /// </exception>
        byte[] ReceiveRawBytes(int bytesToReceive, Timeout timeout, int skipBytes = 0)
            {
            bool receiving = true;
            while (receiving)
                {
                receiving = dataReceivedSignal.WaitOne(timeout, false);
                dataReceivedSignal.Reset();
                if (bufferHead >= bytesToReceive)
                    break; // Got enough data, break out of the receive loop.
                }
            /*
             * We have either received enough data, or timed out waiting.
             */
            if (!receiving)
                throw new SerialReadTimeoutException("Timed out while waiting for " + bytesToReceive.ToString() +
                                                     " bytes");
            var bytesToCopy = bytesToReceive - skipBytes;
            byte[] rawBytes = CopyAndClearReceiveBuffer(bytesToCopy, skipBytes);
            return rawBytes;
            }

        /// <summary>
        ///     Copies the receive buffer into a new byte array, and clears receive buffer.
        ///     This is done in a thread-safe manner.
        /// </summary>
        /// <param name="maxBytesToCopy">
        ///     The maximum number of bytes to receive. Any bytes in the receive buffer beyond the maximum
        ///     are discarded.
        /// </param>
        /// <param name="skipBytes">
        ///     Number of bytes to skip from the start of the receive buffer. Useful for ignoring some leading
        ///     character such as ACK.
        /// </param>
        /// <returns>System.Byte[] containing the contents of the receive buffer.</returns>
        byte[] CopyAndClearReceiveBuffer(int maxBytesToCopy = Int32.MaxValue, int skipBytes = 0)
            {
            lock (receiveBuffer)
                {
                var byteCount = Math.Min(maxBytesToCopy, bufferHead);
                int bytesToCopy;
                if (byteCount + skipBytes >= bufferHead)
                    {
                    // After skipping bytes, there are still enough bytes in the receive buffer to return the requested number of bytes.
                    // We'll return the requested number of bytes and discard the rest.
                    bytesToCopy = byteCount;
                    }
                else
                    {
                    // After skipping bytes, there are too few bytes in the buffer to meet the requested size.
                    // We'll return as many as possible.
                    bytesToCopy = bufferHead - skipBytes;
                    }
                byte[] copy = new byte[bytesToCopy];
                Array.Copy(receiveBuffer, skipBytes, copy, 0, bytesToCopy);
                bufferHead = 0; // Truncate the buffer
                return copy;
                }
            }



#58565 Neduino object oriented motor control in C#

Posted by NameOfTheDragon on 05 June 2014 - 12:11 PM

If anyone is looking for something to get involved in, I have started a project to provide motor control for .net Micro Framework projects, using Netduino hardware and MF 4.3.

 

The project is still 'in flight' and so far I have stepper control working on the Sparkfun Ardumoto shield and am currently working on the Adafruit shield.

 

I would welcome any contributions. The emphasis of the project is on object oriented design and 'clean code' rather than raw performance. I would also love to be able to unit test my MF projects but haven't found a way to do it yet.

 

Anyway, the project is on BitBucket at https://bitbucket.or...mf.motorcontrol

 

Look forward to hearing from you.

--Tim Long




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.