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.

sjmill01

Member Since 25 Oct 2013
Offline Last Active Mar 08 2023 02:31 AM
-----

#63639 Dadbot - Son Makes a Dad Replacement - AND REGRETS IT!

Posted by sjmill01 on 24 July 2015 - 04:38 AM

Although it has a short cameo, the Netduino 3 is endorsed (and used) for a project with my son.  We made a robot that I could control from a hotel room while I am away on business trips.  This robot allows me to keep our learning projects going while I'm away.  

 

As a parent, it still allows me to be involved in parenting as well as you will see at the end in a comedic way.

 

Below is the link to the video.  The video is designed to be shown to his school mates (10 and under).

 

 




#54578 Autonomous R2D2

Posted by sjmill01 on 09 December 2013 - 10:09 PM

1)

 

SEN-00639[color=rgb(51,51,51);font-family:Arial, 'MS Sans Serif', Geneva, sans-serif;] [/color]
[color=rgb(51,51,51);font-family:Arial, 'MS Sans Serif', Geneva, sans-serif;]Ultrasonic Range Finder - Maxbotix LV-EZ1[/color]

 

 

 

[color=rgb(51,51,51);font-family:Arial, 'MS Sans Serif', Geneva, sans-serif;]2)  Yep.  It takes 4 threads to bring it all together. I attached the code below..[/color]

 

[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]These are the current features:[/color]

[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]General:[/color]

  • Selectable Modes: Stick Control, Autonomous Movement
  • Sound: triggers on distance in either mode
  • 4 Threads running at all times: Determining/playing a sound based on distance from an object or time, determining distance from objects in front, setting preferred speed and direction based on the current mode and distance from an object, sending motor drivers pulses based on the preferred speed and direction

[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]Stick Control:[/color]

  • Turning speed scaled down so one doesn't have to be an expert to drive him.
  • Forward movement interlocks if an object is ~2 feet in front

[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]Autonomous Mode:[/color]

  • Object in zone 3, R2 goes forward and turns in the same direction as his last turn. If he doesn't find a clear path in a few seconds, he stops and yells.
  • Object in zone 2, R2 stops and spins in a circle in a random direction. If he doesn't find a clear path in a few seconds, he stops and yells.
  • Objects in zone 1, R2 stops and yells. He then backs up and turns 90 degrees.
  • If object is in zone 14 and the pitch knob is turned up, he'll do a dance to the 8-bit sounding Cantina song.
  • All other zones, R2 drives forward...the further from an object, the faster he goes.

[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]Future:[/color]
[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]Add dome movement[/color]
[color=rgb(63,63,63);font-family:verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;font-size:13.63636302947998px;background-color:rgb(199,218,235);]Add light show control[/color]

using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using System.IO.Ports;namespace R2D2Netduino{    public class Program    {   //v1.0 by Sean J. Miller        static AnalogInput pin_ProximitySensorSignal_Front=new AnalogInput(AnalogChannels.ANALOG_PIN_A0); //a short name for a critical variable I'll be using.        static bool sound_playing = false;  //this is used to prevent clipping a sound that is playing if the person moves from zone to zone.        const bool INTERRUPT_TRACK=true;        const bool DONT_INTERRUPT_TRACK = false;        static SerialPort serial_MP3TriggerBoard = new SerialPort(SerialPorts.COM1, 38400, Parity.None, 8, StopBits.One);        static double temp_front_pin_voltage = 0;        static bool thumbstick_controlled = true;//The default mode where he beeps based on the proximity sensor        static bool pitch_knob_set_on = false;//If autonomous mode is off, pitch_knob_set_on can be flipped on to beep randomly        static bool choreography_routine = false;//This is used to check to see if a pre-programmed movement & sound routine is currently playing to prevent interrupt by another thread.        static int preferred_dome = 0;//The prefferred direction and speed of the dome as determined by the thumbstick or method        static int current_dome = 0;//The last set speed and direction of the dome for comparison logic.        static int preferred_straight_speed = 0;//The preferred direction and speed of the robot in a straight line.  0 is stop -100 is full backwards. 100 is full forwards.        static int current_straight_speed = 0;//The last set speed and direction of the robot in a straight line.        static int preferred_direction = 0;//The preferred direction and speed of the robot turn.  0 is stop -100 is full clockwise. 100 is full counterclockwise.        static int current_direction = 0;//The last set speed and direction of the robot turn.        static double K = 1; //for ramping of motor control        static System.Threading.Timer timer_sound_reset;//this is to auto reset sound_playing to false after 20 seconds just in case I miss the serial RX event.        static TimerCallback myTimerCallbackMethod;        static double distance_increment = .06; //distance increment is an analog voltage increment.  Used Debug.Print to assess values for the zones.        static int front_distance_zone = 10;//this is to track which increment zone the object is in per the proximity sensor.  It starts out at 10 arbitrarily.        static Random random_number = new Random();        static InterruptPort inputPort5_Gear, inputPort6_PitTrim, inputPort7_LeftThumbHorizontalChannel3, inputPort12_RightThumbChannel1, inputPort13_RightThumbChannel2;        static long leadingEdge5 = 0;//Used to time the PWM from Channel 5 on pin 5        static long leadingEdge6 = 0;//Used to time the PWM from Channel 6 on pin 6        static long leadingEdge7 = 0;//Used to time the PWM from Channel 3 on pin 7        static long leadingEdge12 = 0;//Used to time the PWM from Channel 1 on pin 12        static long leadingEdge13 = 0;//Used to time the PWM from Channel 2 on pin 13        static long currentPulseWidth7, currentPulseWidth12, currentPulseWidth13; //used to pulse out PWM on pins 7, 12, and 13 (dome, speed, direction)        static SecretLabs.NETMF.Hardware.PWM PWM_DomeMovementToPin9, PWM_StraightMovementToPin10, PWM_TurnMovementToPin11;  //Dome, Straight Line, and Turn pulses to motor drivers        static Thread movementThread, soundThread, distanceThread, pulseThread;//One thread to handle dome and feet motors and the other is to handle playing sounds.        public static void Main()        {   //This initiates the program and starts the forever looping routine named update.            //R2D2Netduino.Program my_program = new R2D2Netduino.Program();            //my_program.init();            myTimerCallbackMethod = new TimerCallback(clearTime);            timer_sound_reset = new System.Threading.Timer(myTimerCallbackMethod, null, 20000, 60000);//used to reset audio the Netduino misses the X sent back by the MP3Trigger Board            serial_MP3TriggerBoard.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler_TriggerBoard);            serial_MP3TriggerBoard.Open(); serial_MP3TriggerBoard.Flush();            inputPort5_Gear = new InterruptPort(Pins.GPIO_PIN_D5, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            inputPort5_Gear.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt5);            inputPort6_PitTrim = new InterruptPort(Pins.GPIO_PIN_D6, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            inputPort6_PitTrim.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt6);            inputPort7_LeftThumbHorizontalChannel3 = new InterruptPort(Pins.GPIO_PIN_D7, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            inputPort7_LeftThumbHorizontalChannel3.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt7);            inputPort12_RightThumbChannel1 = new InterruptPort(Pins.GPIO_PIN_D12, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            inputPort12_RightThumbChannel1.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt12);            inputPort13_RightThumbChannel2 = new InterruptPort(Pins.GPIO_PIN_D13, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            inputPort13_RightThumbChannel2.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt13);            PWM_DomeMovementToPin9 = new SecretLabs.NETMF.Hardware.PWM(Pins.GPIO_PIN_D9);            PWM_StraightMovementToPin10 = new SecretLabs.NETMF.Hardware.PWM(Pins.GPIO_PIN_D10);            PWM_TurnMovementToPin11 = new SecretLabs.NETMF.Hardware.PWM(Pins.GPIO_PIN_D11);            soundThread = new Thread(performSound);            soundThread.Start();//start the thread that beeps and bloops            movementThread = new Thread(performMovements);            movementThread.Start();//start the thread that handles movement            distanceThread = new Thread(checkAndSetDistance);            distanceThread.Start();//start the thread that categorizes distance from objects into zones which is used to rome autonomously or fire interlocks on thumbstick control            pulseThread = new Thread(pulseToMotorDrivers);            pulseThread.Start();            Thread.Sleep(Timeout.Infinite);//sleep and let the threads do their magic        }        static void checkAndSetDistance()        {   //Identify what zone the object is that is infront of the robot.  It runs in the distanceThread, so            //we will always be aware of the distance from the sensors.            while (true)            {                temp_front_pin_voltage = pin_ProximitySensorSignal_Front.Read();                                if (temp_front_pin_voltage < distance_increment) front_distance_zone = 1;                else if (temp_front_pin_voltage < 2 * distance_increment) front_distance_zone = 2;                else if (temp_front_pin_voltage < 3 * distance_increment) front_distance_zone = 3;                else if (temp_front_pin_voltage < 4 * distance_increment) front_distance_zone = 4;                else if (temp_front_pin_voltage < 5 * distance_increment) front_distance_zone = 5;                else if (temp_front_pin_voltage < 6 * distance_increment) front_distance_zone = 6;                else if (temp_front_pin_voltage < 7 * distance_increment) front_distance_zone = 7;                else if (temp_front_pin_voltage < 8 * distance_increment) front_distance_zone = 8;                else if (temp_front_pin_voltage < 9 * distance_increment) front_distance_zone = 9;                else if (temp_front_pin_voltage < 10 * distance_increment) front_distance_zone = 10;                else if (temp_front_pin_voltage < 11 * distance_increment) front_distance_zone = 11;                else if (temp_front_pin_voltage < 12 * distance_increment) front_distance_zone = 12;                else if (temp_front_pin_voltage < 13 * distance_increment) front_distance_zone = 13;                else if (temp_front_pin_voltage < 14 * distance_increment) front_distance_zone = 14;                Thread.Sleep(250);            }        }        static void performSound()        {   //This is the main program that monitors sensors and loops infinitely.            int last_front_distance_zone = -1;//set initially to something that will ensure sound is triggered initially.            int ticker = 0;//used to trigger on time.            while (true)            {                                if (last_front_distance_zone!=front_distance_zone)                {   //trigger on distance                    PlayTrack(randomInRange(front_distance_zone),DONT_INTERRUPT_TRACK);                    last_front_distance_zone=front_distance_zone;//this keeps him from chattering too much.                }                                if (ticker++>30) {                    //trigger on time                    PlayTrack(random_number.Next(182),DONT_INTERRUPT_TRACK);                    ticker = 0;                }                Thread.Sleep(500);            }        }        static void setDomeStickPreferredSpeedAndDirection()        {            if (currentPulseWidth7 > 14810)            {                preferred_dome = (int)(100 - 100 * (18960 - currentPulseWidth7) / (18960 - 14810));            }            else if (currentPulseWidth7 > 14800 && currentPulseWidth7 < 14820)            {                preferred_dome = 0;            }            else            {                preferred_dome = (int)(100 * (currentPulseWidth7 - 14820) / (14820 - 10640));            }        }        static void setRobotStickPreferredSpeed()        {            if (currentPulseWidth12 > 14810)            {//Forward                if (front_distance_zone==1)                {                   preferred_straight_speed = 0;//this is to interlock forward movement if something is super close.                   PlayTrack(132, DONT_INTERRUPT_TRACK);                }  else preferred_straight_speed = (int)(100 - 100 * (18960 - currentPulseWidth12) / (18960 - 14810));            }            else if (currentPulseWidth12 > 14800 && currentPulseWidth12 < 14820)            {//stopped                preferred_straight_speed = 0;            }            else            {   //reverse                  preferred_straight_speed = (int)(100 * (currentPulseWidth12 - 14820) / (14820 - 10640));            }        }        static void setRobotStickPreferredDirection()        {            if (currentPulseWidth13 > 14810)            {                preferred_direction = (int)(100 - 100 * (18960 - currentPulseWidth13) / (18960 - 14810));            }            else if (currentPulseWidth13 > 14800 && currentPulseWidth12 < 14820)            {                preferred_direction = 0;            }            else            {                preferred_direction = (int)(100 * (currentPulseWidth13 - 14820) / (14820 - 10640));            }        }        static void pulseToMotorDrivers()        {            while(true)            {                //Pulse Straight Speed                if (preferred_straight_speed == 0)                {                    PWM_StraightMovementToPin10.SetPulse(20000, (uint)(1500));                    current_straight_speed = 0;                }                else if (System.Math.Abs(preferred_straight_speed - current_straight_speed) >5)                {                    current_straight_speed = current_straight_speed + (int)(K * (preferred_straight_speed - current_straight_speed));                    PWM_StraightMovementToPin10.SetPulse(20000, (uint)(1500 + (5 * current_straight_speed)));                }                        //Pulse Direction                if (preferred_direction == 0)                {                    PWM_TurnMovementToPin11.SetPulse(20000, (uint)(1500));                    current_direction = 0;                 }                else if (System.Math.Abs(preferred_direction - current_direction) >5)                {                    current_direction = current_direction + (int)(K * (preferred_direction - current_direction));                    PWM_TurnMovementToPin11.SetPulse(20000, (uint)(1500 + (3 * current_direction)));                }                //Pulse dome                if (System.Math.Abs(preferred_dome - current_dome) > 5)                {                    PWM_DomeMovementToPin9.SetPulse(20000, (uint)(1500 + (5 * preferred_dome)));                    current_dome = preferred_dome;                }                     Thread.Sleep(100);            }        }        static void performMovements()        {            while (true)            {                if (thumbstick_controlled)                {   //If the gear switch is down, then it will turn off the choreography routine and                     //use the sticks on the controller for input.                    if (!choreography_routine)//this lets the choreography routine finish up before taking over with stick controll.                    {                        setDomeStickPreferredSpeedAndDirection();                        setRobotStickPreferredDirection();                        setRobotStickPreferredSpeed();                    }                }                else if (!choreography_routine)                {   //if the gear switch is flipped up and the pitch is turned up, it will trigger                    //the choreography if not already triggered.                                            choreography_routine = true;                        //performCantinaDance();  someday, I need to add another remote trigger                        romeAroundAutonomously();                        choreography_routine = false;                        sound_playing = false;                        PlayTrack(2, DONT_INTERRUPT_TRACK);                        Thread.Sleep(1000);//give some time to remember to flip to thumbstick control if desired.                                    }                else stopRobot();                                 Thread.Sleep(100);            }        }        static private void stopRobot()        {   //this is written with a Dimension Engineering Sabertooth 2x.. Motor Driver in Mind            preferred_straight_speed=0;            preferred_direction=0;        }        static private void romeAroundAutonomously()        {            PlayTrack(177, INTERRUPT_TRACK);            int ii = 0; int last_direction = 50;            stopRobot();//if already moving...stop it.            Thread.Sleep(500);//give his bones a rest before taking off again.            while (true)            {                   if (thumbstick_controlled) { stopRobot(); return; }                if (front_distance_zone == 1)                {                    stopRobot();//just about hit something, so stop and yell!                    PlayTrack(132, INTERRUPT_TRACK);                    Thread.Sleep(1000);                    preferred_straight_speed = -55;                    preferred_direction = last_direction;                    Thread.Sleep(1500);                    stopRobot();                    Thread.Sleep(3000);//give the owner time to flip to thumbstick control                    return;                }                else if (front_distance_zone == 2)                {   //if we are in Zone 2, we need to just stop and turn until we find a hole to drive through.                    preferred_straight_speed=0;                    preferred_direction=80-160*(random_number.Next(2));                    last_direction = preferred_direction;                                        ii = 0;                    while (front_distance_zone < 3 && ii < 55)                    {   //if we don't find a hole to drive through in a few seconds of turning, just yell for help.                         ii++;                        Thread.Sleep(250);                        if (thumbstick_controlled) { stopRobot(); return; }                    }                    stopRobot();                    if (ii >= 55)                    {//couldn't find a hole, so yell it up to have the owner take control.                        PlayTrack(132, INTERRUPT_TRACK);                        Thread.Sleep(4000);//give the owner time to respond with flipping back to control.                        return;//get out of this movement.                    }                    preferred_straight_speed=30;//if we made it here, then we found a hole...move slowly ahead.                                    }                else if (front_distance_zone == 3)                {   //if we are in zone 3, we need to slow down and turn sharp until we find a hole to drive through.                    preferred_straight_speed=30;                    preferred_direction = (int)((double)last_direction*1.1);                                        if (thumbstick_controlled) { stopRobot(); return; }                    ii = 0;                    while (front_distance_zone < 4 && ii < 55)                    {   //if we don't find a hole to drive through in a few seconds of turning, just yell for help.                         ii++;                        if (front_distance_zone < 3)                        {                            stopRobot();                            break;                        }                        Thread.Sleep(100);                        if (thumbstick_controlled) { stopRobot(); return; }                    }                    stopRobot();                    if (ii >= 55)                    {//couldn't find a hole, so yell it up to have the owner take control.                        PlayTrack(132, INTERRUPT_TRACK);                        Thread.Sleep(2000);//give the owner time to respond with flipping back to control.                        return;//get out of this movement.                    }                    preferred_straight_speed=35;                }                else if (front_distance_zone == 4)                {                    preferred_direction=0;                    preferred_straight_speed=35;                }                else if (front_distance_zone == 5)                {                    preferred_direction=0;                    preferred_straight_speed=38;                }                else if (front_distance_zone == 6)                {                    preferred_direction = 0;                    preferred_straight_speed = 40;                }                else if (front_distance_zone == 7)                {                    preferred_direction = 0;                    preferred_straight_speed = 42;                }                else if (front_distance_zone == 8)                {                    preferred_direction = 0;                    preferred_straight_speed = 45;                }                else if (front_distance_zone == 9)                {                    preferred_direction = 0;                    preferred_straight_speed = 48;                }                else if (front_distance_zone == 10)                {                    preferred_direction = 0;                    preferred_straight_speed = 50;                }                else if (front_distance_zone == 11 || front_distance_zone == 12 || front_distance_zone == 13)                {                    preferred_direction = 0;                    preferred_straight_speed = 52;                }                else if (pitch_knob_set_on)                {                    stopRobot();                    Thread.Sleep(1000);                    performCantinaDance();                    Thread.Sleep(2000);                }                Thread.Sleep(100);            }        }        static private void performCantinaDance()        {            stopRobot();            PlayTrack(13,INTERRUPT_TRACK);            preferred_direction=(80+random_number.Next(20));            Thread.Sleep(1000 + random_number.Next(2000));            preferred_direction=(0);            if (thumbstick_controlled) return;                        Thread.Sleep(500 + random_number.Next(250));            if (thumbstick_controlled) return;            preferred_direction=(-(80 + random_number.Next(20)));            Thread.Sleep(1000 + random_number.Next(2000));            preferred_direction=(0);            if (thumbstick_controlled) return;            Thread.Sleep(500+random_number.Next(250));            preferred_direction=(80 + random_number.Next(20));            Thread.Sleep(1000 + random_number.Next(2000));            preferred_direction=(0);            if (thumbstick_controlled) return;            Thread.Sleep(500 + random_number.Next(250));            preferred_direction=(-(80 + random_number.Next(20)));            Thread.Sleep(1000 + random_number.Next(2000));            stopRobot();            if (thumbstick_controlled) return;            Thread.Sleep(500 + random_number.Next(250));            preferred_direction = (-(80 + random_number.Next(20)));            Thread.Sleep(1000 + random_number.Next(2000));            stopRobot();            if (thumbstick_controlled) return;            Thread.Sleep(500 + random_number.Next(250));            preferred_direction = (-(80 + random_number.Next(20)));            Thread.Sleep(1000 + random_number.Next(2000));            stopRobot();            if (thumbstick_controlled) return;                        Thread.Sleep(2000);        }        static void inputPort_OnInterrupt5(uint data1, uint data2, DateTime time)        {   //RC Channel 5 Reading in (Gear)            if (data2 == 1) leadingEdge5 = time.Ticks; else if ((long)((time.Ticks - leadingEdge5)) >= 17000) thumbstick_controlled = false; else thumbstick_controlled = true;        }        static void inputPort_OnInterrupt6(uint data1, uint data2, DateTime time)        {//RC Channel 6 Reading in (Pit Trim)            if (data2 == 1) leadingEdge6 = time.Ticks; else if ((long)((time.Ticks - leadingEdge6)) > 16000) pitch_knob_set_on = false; else pitch_knob_set_on = true;        }        static void inputPort_OnInterrupt12(uint data1, uint data2, DateTime time)        {   //RC Channel 12            if (data2 == 1) leadingEdge12 = time.Ticks; else currentPulseWidth12 = (time.Ticks - leadingEdge12);        }        static void inputPort_OnInterrupt13(uint data1, uint data2, DateTime time)        {   //RC Channel 13            if (data2 == 1) leadingEdge13 = time.Ticks; else currentPulseWidth13 = (time.Ticks - leadingEdge13);        }        static void inputPort_OnInterrupt7(uint data1, uint data2, DateTime time)        {//RC Channel 3            if (data2 == 1) leadingEdge7 = time.Ticks; else currentPulseWidth7 = (time.Ticks - leadingEdge7);        }        static private void clearTime(object state)        {   //This is called by timer_sound_reset thread every 20 seconds as a safety net for the serial event handler not catching the "track ended" response from the trigger board.            sound_playing = false;            timer_sound_reset.Change(20000, 60000);//resets the timer.        }        static private void DataReceivedHandler_TriggerBoard(object sender, SerialDataReceivedEventArgs e)        {   //This is triggered whenever some TTL is piped into Digital pin 0.            if (((SerialPort)sender).ReadByte() == 88) sound_playing = false;//check for the Letter X from MP3Triggerboard.  This signals the track is finsihed playing.        }        static private int randomInRange(int the_distance)        {            return (the_distance * 10 + random_number.Next(10));//This gives a random number to select random tracks within a zone.        }        static private void PlayTrack(int ii, bool interrupt)        {   //Sparkfun MP3TriggerBoard Only!            //first, we ensure we don't interrupt a playing track if so desired.            if (!sound_playing||interrupt==INTERRUPT_TRACK)            {                sound_playing = true;                timer_sound_reset.Change(20000, 60000);//resets the timer.                byte the_track = (byte)(ii);                serial_MP3TriggerBoard.Write(new byte[] { 0x74, the_track }, 0, 2);//write out the serial to the MP3Trigger board which is the letter t followed by a byte value of 1-255.            }        }                static private void setVolume(int ii)        {//Sparkfun MP3TriggerBoard Only!            byte the_setting = (byte)(ii);//according to the MP3Trigger Board, 0 is the loadest and 64 can't be heard.            serial_MP3TriggerBoard.Write(new byte[] { 0x76, the_setting }, 0, 2);        }    }}



#54239 Autonomous R2D2

Posted by sjmill01 on 23 November 2013 - 02:26 AM

This is a very early showcase of the code I wrote for the Netduino to control an R2D2.  To build the R2 this far, it took over 2 years of research, wood, plastic, and aluminum work.  I'm now back in my wheelhouse with programming and am loving the Netduino Plus 2.

 

http://www.youtube.c...h?v=vLJb6dg859Y




#53762 Netduino Plus 2 RC Reading Works for Me?

Posted by sjmill01 on 01 November 2013 - 12:02 AM

In the last few days, I cobbled some code that seems to use the Netduino Plus 2 PWM pins to reliably read data from an RC receiver.

 

While searching the web for code, I found countless posts that the Netduino Plus 2 either can't do it or is not reliable to do it.  But, I'm living proof that it does it.

 

Is this just an "Apple vs. PC"-like phenomenon on the web, or should I not trust the Netduino Plus 2 to reliably read RC data - particularly in the application of motor control?

 

So far, I'm only using it to trigger audio on an MP3Trigger.  However, my next target is to receive drive and direction from an RC controller, process it against sensors with the Netduino Plus 2, and then send the appropriate PWM to the motor driver.

 

Thanks in advance for any advice,

Sean




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.