Steppers con arduino C# y comunicacion serial **FUNCIONANDO**

En esta version, se investigó el tope de tamaño de buffer serial de arduino (64K), y se hicieron varias pruebas para exceder ese limite, observandose anomalìas en el funcionamiento.
El ejemplo adjunto funciona correctamente, si se trata de exceder en un octeto mas, ya no funciona.

OJO! También se agregó Serial.flush() antes de comenzar.

Código arduino:

//#include <QueueArray.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2); //set the LCD address to 0x27 for a 16 chars and 2 line display

int motor1[] = {  4, 5, 6, 7 }; 
int motor2[] = {  8, 9, 10, 11 };  

String incomingString;
String buffer_ant = "";
String buffer = "";
boolean fin_datos;

void setup() {  
    lcd.init(); 
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("www.b2cqshop.com");
    lcd.setCursor(0, 1);
    lcd.print("Voltage: ");
    lcd.setCursor(13, 1);
    lcd.print("V");


    Serial.begin(9600);

    fin_datos = false;

    DDRD = B11111111; // set PORTD (digital 7~0)  
    DDRB = B11111111; // set PORTB (digital 13~8)
  
    paso(0, "stop");  
  
    Serial.flush();
    
    buffer = "";
    incomingString = "";
}

void paso(int motor, String dir)
{
  static int paso_actual_motor1 = 1;
  static int paso_actual_motor2 = 1;
    
  if (dir == "stop")
  {
      PORTD = B00000000;
      PORTB = B00000000;        
  }
  
  if (motor == 1)
  {
    if (dir == "derecha")
    {
      paso_actual_motor1++;
      if (paso_actual_motor1 > 4)
        paso_actual_motor1 = 1;
    } else if (dir == "izquierda")
    {
      paso_actual_motor1--;
      if (paso_actual_motor1 < 1)
        paso_actual_motor1 = 4;          
    }    
    
    switch (paso_actual_motor1)
    {
      case 1: 
          //       76543210
          PORTD = B00010000;
          
          break;
         
      case 2:
          //       76543210
          PORTD = B00100000;
  
          break;
       
      case 3:
          //       76543210
          PORTD = B01000000;
      
          break;
          
      case 4:
          //       76543210
          PORTD = B10000000;
      
          break;
          
      default: break;
    }           
  }
  
  if (motor == 2)
  {
    if (dir == "derecha")
    {
      paso_actual_motor2++;
      if (paso_actual_motor2 > 4)
        paso_actual_motor2 = 1;
    } else if (dir == "izquierda")
    {
      paso_actual_motor2--;
      if (paso_actual_motor2 < 1)
        paso_actual_motor2 = 4;          
    }    
    
    switch (paso_actual_motor2)
    {
      case 1: 
          //             98
          PORTB = B00000001;
          
          break;
         
      case 2:
          //       76543210
          PORTB = B00000010;
  
          break;
       
      case 3:
          //       76543210
          PORTB = B00000100;
      
          break;
          
      case 4:
          //       76543210
          PORTB = B00001000;
      
          break;
          
      default: break;
    }           
  }
  
}

void mover_motores(String buffer)
  if (buffer[7] != buffer_ant[7])
  {
    if (buffer[3] == '1')
      paso(1, "derecha");
    else
      paso(1, "izquierda");      
  }  
  
  buffer_ant = buffer;
  
  delay(10);
}

void push(String dato)
{
  buffer += dato;  
}

String pop()
{
  String s;

  s = buffer.substring(0, 8);
  if (buffer.length() > 8)
    buffer = buffer.substring(8);  
  else
    buffer = "";
    
   return s;
}

boolean queue_empty()
{
   return (buffer.length() == 0);
}

//************************ LOOP ******************************//
void loop() 
{

  if (Serial.available() > 0) 
  {
    char incomingByte = Serial.read();    

    if (incomingByte == '\0') 
    {      
      if (incomingString == "XXXXXXXX")
        fin_datos = true;
      else
      {
        push(incomingString);
      } 

      incomingString = "";
    } else
        incomingString += incomingByte;   
  } 

  if (fin_datos)
  {   
    while (!queue_empty())
    {
      String octeto = pop();   
      mover_motores(octeto);
    }
    
    paso(0, "stop");          
    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Inactivo");
    
    Serial.flush();
    
    fin_datos = false;
  }
  
}


Código .net

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Runtime.InteropServices;
using System.Collections;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        static Queue<String> q = new Queue<String>();

        static String mensaje = "";

        ArrayList arr;
        static long cant_queue;
        static bool comienzo = false;

        int paso = 1;
        String buffer;   //voy a usar de 1 a 8, el cero lo ignoro.
        String buffer_ant;

        String str_recibido = "";

        String log = "";
        static bool enviar_a_arduino = false;

        [DllImport("inpout32.dll", EntryPoint = "Out32")]
        public static extern void Output(int adress, int value);

        [DllImport("inpout32.dll", EntryPoint = "Inp32")]
        public static extern short Input(int adress);
        static SerialPort port;

        public Form1()
        {
            InitializeComponent();
        }

        
         

        void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int bytesToRead = port.BytesToRead;
            char[] z = new char[bytesToRead];
            port.Read(z, 0, bytesToRead);

            // ESTO NO VA ACA!!!!!!!  str_recibido = "";   
            //PORQUE SI VA ACA, COMO NO RECIBE TODA LA LINEA DE UN SAQUE, CUANDO VUELVE A DISPARARSE ESTE EVENTO LO PONE VACIO DE NUEVO.

            foreach (char s in z)
            {
                if (s == '\0')
                {
                    Console.WriteLine(str_recibido);
                    str_recibido = "";
                }
                else
                    str_recibido += s;
            }
        }

        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //Write the serial port data to the console.
            Console.WriteLine(port.ReadExisting());
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {               
                port = new System.IO.Ports.SerialPort("COM17", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);


                //port.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);

                port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived);
                port.Open();

                

            } catch(Exception ex)
            {
                MessageBox.Show("No se pudo abrir com17: " + ex.Message);
            }


        }

        private void prueba()
        {
            Queue<String> q = new Queue<String>();

            q.Enqueue("abc");
            q.Enqueue("zzz");
            q.Enqueue("fff");
            q.Enqueue("hhh");

            while (cant_queue > 0)
            {
                Console.WriteLine(q.Dequeue());
                cant_queue--;
            }

            //foreach (String v in q)
           // {
            //    Console.WriteLine(v);
           // }

        }

        private void cmdMonitorLPT_Click(object sender, EventArgs e)
        {
            short v, v_ant;
            int cant_ceros = 0;

            buffer_ant = "        ";   // pin2_ant = ""; 

            Step("stop");

            if (cmdMonitorLPT.Text == "Monitor LPT")
            {
                arr = new ArrayList();

                cmdMonitorLPT.Text = "Detener";
                Application.DoEvents();                

                v = 0;
                v_ant = -1;

                while (v == 0)
                {
                    v = leerLPT();   
                }

                do
                {
                    if (v != v_ant)
                    {
                        EnviarArduino();  

                        v_ant = v;
                    }

                    v = leerLPT();

                    if (v == v_ant)
                        cant_ceros++;
                    else
                        cant_ceros = 0;

                } while (cant_ceros < 600000);

                Step("stop");
            } else            
                cmdMonitorLPT.Text = "Monitor LPT";            
        }

        private short leerLPT()
        {
            short v;

            v = Input(888);
            buffer = Convert.ToString(v, 2).PadLeft(8, '0');

            return v;
        }

        private void EnviarArduino()
        {
            char pin2, pin6;
            
            pin2 = buffer[7];    //.Substring(7, 1);
            pin6 = buffer[3];    // t.Substring(3, 1);            

            if (buffer[7].CompareTo(buffer_ant[7]) != 0)    //pin2.CompareTo(pin2_ant) != pin2_ant)
            {
                if (buffer[3] == '0')     //pin6 == "0")
                {
                    port.Write(paso.ToString());
                    paso++;
                    if (paso > 4)
                        paso = 1;
                }
                else
                {
                    port.Write(paso.ToString());
                    paso--;
                    if (paso < 1)
                        paso = 4;
                }

                buffer_ant = buffer;
                //pin2_ant = pin2;
                
                System.Threading.Thread.Sleep(2);
            }

        }

        public static int ToDecimal(string bin)
        {
            long l = Convert.ToInt64(bin, 2);
            int i = (int)l;
            return i;
        }

        private void Step(String dir)
        {            
            switch (dir)
            {
                case "der" :
                    port.Write(paso.ToString());
                    paso++;
                    if (paso > 4)
                        paso = 1;
                    break;

                case "izq":
                    port.Write(paso.ToString());
                    paso--;
                    if (paso < 1)
                        paso = 4;
                    break;

                case "stop":
                    port.Write("X");
                    break;
            }

        }

        private static void enviarOctetosANT(int cant)
        {
            int i = cant;
            String s = ""; String octeto = "";
            bool fin_datos = false;

            while (i > 0 && cant_queue > 0 && !fin_datos)
            {
                octeto = q.Dequeue();
                if (octeto == "TERMINO")
                {
                    s += "{" + octeto + "}";

                    fin_datos = true;
                    q.Clear();
                    cant_queue = 0;

                    
                } else
                {
                    s += "{" + octeto + "}";

                    i--;
                    cant_queue--;
                }                
            }

            if (!fin_datos)
                s += "{FIN}";     //FIN indica que termino el set de octetos. TERMINO indica que termino todo.

            port.Write(s);
        }

        private static void enviarOctetos(int cant)
        {
            int i = cant;
            String s = ""; String octeto = "";
            bool fin_datos = false;

            while (i > 0 && cant_queue > 0 && !fin_datos)
            {
                octeto = q.Dequeue();
                if (octeto == "TERMINO")
                {
                    s += "{" + octeto + "}";

                    fin_datos = true;
                    q.Clear();
                    cant_queue = 0;


                }
                else
                {
                    s += "{" + octeto + "}";

                    i--;
                    cant_queue--;
                }
            }

            if (!fin_datos)
                s += "{FIN}";     //FIN indica que termino el set de octetos. TERMINO indica que termino todo.

            port.Write(s);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            short v, v_ant;
            int cant_ceros = 0;

            buffer_ant = "";   // pin2_ant = ""; 

            Step("stop");

            if (cmdMonitorLPT.Text == "Monitor LPT")
            {
                arr = new ArrayList();

                cmdMonitorLPT.Text = "Detener";
                Application.DoEvents();

                v = 0;
                v_ant = -1;

                while (v == 0)
                {
                    v = leerLPT();
                }

                do
                {
                    if (v != v_ant)
                    {
                        EnviarArduino();

                        v_ant = v;
                    }

                    v = leerLPT();

                    if (v == v_ant)
                        cant_ceros++;
                    else
                        cant_ceros = 0;

                } while (cant_ceros < 600000);

                Step("stop");
            }
            else
                cmdMonitorLPT.Text = "Monitor LPT";            

        }

        private void button6_Click(object sender, EventArgs e)
        {
            comienzo = false;
            
            q.Clear();
            cant_queue = 0;

            Thread t1 = new Thread(new ParameterizedThreadStart(monitorLPT));
            t1.Start();
        }

        private static void enviarDatosArduino()
        {
            if (cant_queue > 0)
            {
                //ESTA BIEN! SE EJECUTA 2 VECES PORQUE MANDA 1RO LOS 50 Y LUEGO LOS 22 (SON 72 EN TOTAL)

                enviarOctetos(200);
            }
        }

        private static void envioArduino(object num)
        {
            while (true)
            {
                if (cant_queue > 100)
                {
                    port.Write("S");
                    comienzo = true;
                }

                if (enviar_a_arduino)
                {
                    enviar_a_arduino = false;
                    enviarOctetos(50);
                }

                Thread.Sleep(200);
            }
        }
        private static void CargarArchivo(object num)
        {
            cant_queue = 0;

            System.IO.StreamReader sr = new System.IO.StreamReader(Application.StartupPath  + "..\\..\\..\\archivos\\a2.txt");
            while (!sr.EndOfStream)
            {
                String linea = sr.ReadLine();
                q.Enqueue(linea);

                cant_queue++;
            }

            sr.Close();
        }
        private static void monitorLPT(object num)
        {
            short v, v_ant;
            int cant_ceros = 0;
            String octeto = "";
            //bool comenzo_arduino = false;
            

            v = 0;
            v_ant = -1;



            while (v == 0)
            {
                v = Input(888);
                octeto = Convert.ToString(v, 2).PadLeft(8, '0');

                //v = leerLPT();
            }

            do
            {
                if (v != v_ant)
                {
                    

                    q.Enqueue(octeto);
                    cant_queue++;

                    //Console.WriteLine("Guardando en queue: " + octeto + "  Cantidad: " + cant_queue);

                    //if (cant_queue > 100 && !comenzo_arduino)
                    //{
                    //    port.Write("S");   //luego que cargue 100 en el buffer, le digo a arduino que comience
                    //    comenzo_arduino = true;
                    //}

                    //EnviarArduino();

                    v_ant = v;
                } else
                {
                    mensaje = "Evitando duplicados...";
                }


                v = Input(888);
                octeto = Convert.ToString(v, 2).PadLeft(8, '0');

                if (v == v_ant)
                    cant_ceros++;
                else
                    cant_ceros = 0;

            } while (true);   // (cant_ceros < 600000);            
        }

        private void MoverMotores()
        {
            for (int i = 0; i < 6; i++)
            {
                port.Write("00010001\0");
                port.Write("00010000\0");
                port.Write("00010001\0");
                port.Write("00010000\0");
                port.Write("00010001\0");
                port.Write("00010000\0");
                port.Write("00010001\0");
                port.Write("00010000\0");
            }

            port.Write("00010001\0");
            port.Write("XXXXXXXX\0");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            MoverMotores();
        }
    }
}


Comunicacion serial entre Arduino y C#

En este ejemplo, la aplicación C# envia lineas al arduino, el arduino las despliega en un display lcd y luego las envia a C#, y C# las despliega en la consola:


En arduino:

void setup()
{
    Serial.begin(9600);
    incomingString = "";
}


void loop()
{
  if (Serial.available() > 0)
  {
    char incomingByte = Serial.read();  

    if (incomingByte == '\0')
    {
      disp(incomingString);

      Serial.print(incomingString);
      Serial.print('\0');
     
      incomingString = "";
    } else
        incomingString += incomingByte;  
  }
}


En C#:

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {               
                port = new System.IO.Ports.SerialPort("COM17", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);

                port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived);
                port.Open();                
            } catch(Exception ex)
            {
                MessageBox.Show("No se pudo abrir com17: " + ex.Message);
            }
        }

        void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int bytesToRead = port.BytesToRead;
            char[] z = new char[bytesToRead];
            port.Read(z, 0, bytesToRead);

            // ESTO NO VA ACA!!!!!!!  str_recibido = "";   
            //PORQUE SI VA ACA, COMO NO RECIBE TODA LA LINEA DE UN SAQUE, CUANDO VUELVE A DISPARARSE ESTE EVENTO LO PONE VACIO DE NUEVO.

            foreach (char s in z)
            {
                if (s == '\0')
                {
                    Console.WriteLine(str_recibido);
                    str_recibido = "";
                }
                else
                    str_recibido += s;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {            
            port.Write("prueba1\0");            
            port.Write("prueba2\0");            
            port.Write("prueba3\0");            
            port.Write("prueba4\0");            
            port.Write("prueba5\0");
        }




Control remoto IR con Arduino

Ojo! este codigo y la libreria funcionan con el IDE 0022.

*************** ESTA ES LA SOLUCION PARA QUE FUNCIONE CON IDE 1.0.1 *******

go to where you installed arduino IDE, and go to the IRremote library folder and find IRremoteInt.h ex "C:\Users\Robert\Desktop\arduino-1.0\libraries\IRremote\IRremoteInt.h"

towards the top of this text file you should see something like:
Code:
#include "WProgram.h"
replace it with:
Code:
#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
  #include <pins_arduino.h>
#endif

teda... it works

Fuente: http://arduino.cc/forum/index.php?action=printpage;topic=96719.0
 ***************************************************************************

http://www.e-shore.com.my/homepage/all-projects/193-ir-remote-control-mobile-robot.html#oogleto:http://www.e-shore.com.my/homepage/images/mo/100511_0333_IRRemoteCon7.png



/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {


  if (irrecv.decode(&results)) {
    if(results.value==0xFF30CF)
    {
      Serial.println("NUMERO 1");
    } else
    {
      Serial.println(results.value, HEX);
    }
    //Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
}

Activar varios pines de Arduino simultáneamente


http://tronixstuff.wordpress.com/2011/10/22/tutorial-arduino-port-manipulation/

http://www.arduino.cc/en/Reference/PortManipulation

Sometimes you might need to set multiple output pins at exactly the same time. Calling digitalWrite(10,HIGH); followed by digitalWrite(11,HIGH); will cause pin 10 to go HIGH several microseconds before pin 11, which may confuse certain time-sensitive external digital circuits you have hooked up. Alternatively, you could set both pins high at exactly the same moment in time using PORTB |= B1100;

Crear un excel connection manager dinámico

En la propiedad Expressions del connection manager:

"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + @[User::arch_destino] + ";Extended Properties=\"EXCEL 12.0 XML;HDR=YES\";"

Siendo @[User::arch_destino] una variable.

Error al abrir excel generado con ssis

Hay que agregrle XML al connection string:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\temp\aa.xlsx;Extended Properties="EXCEL 12.0 XML;HDR=YES";

Paul McCartney en Uruguay

Fecha: Domingo 15 de Abril de 2012, hora 20:30

Lista de temas:

1. Hello, Goodbye (The Beatles)
2. Junior's Farm (Wings)
3. All My Loving (The Beatles)
4. Jet (Wings)
5. Got to Get You into My Life (The Beatles)
6. Sin the Changes (The Fireman)
7. The Night Before (The Beatles)
8. Let Me Roll It (Wings)
9. Papaerback Writer (The Beatles)
10. The Long and Winding Road (The Beatles)
11. Nineteen Hundred and Eighty-Five (Wings)
12. My Valentine
13. Maybe I'm Amazed
14. I'm Looking Thorugh You (The Beatles)
15. Two of Us (The Beatles)
16. Blackbird (The Beatles)
17. Here Today
18. Dance Tonight
19. Mrs. Vandebilt (Wings)
20. Eleanor Rigby (The Beatles)
21. Something (The Beatles)
22. Band on the Run (Wings)
23. Ob-La-Di, Ob-La-Da (The Beatles)
24. Back in the U.S.S.R. (The Beatles)
25. I've Got a Feeling (The Beatles)
26. A Day in the Life (The Beatles)
27. Let It Be (The Beatles)
28. Live and Let Die (Wings)
29. Hey Jude (The Beatles)


Encore:
30. Lady Madonna (The Beatles)
31. Day Tripper (The Beatles)
32. Get Back (The Beatles)

Encore 2:
33. Yesterday (The Beatles)
34. Helter Skelter (The Beatles)
35. Golden Slumbers (The Beatles)
36. Carry That Weight (The Beatles)
37. The End (The Beatles)

Japon 2012

Dejan embarcar 1 sola valija de hasta 23kg
-Pagar mentoría
-Averiguar cuantos yenes llevar
-Tarjetas de memoria para filmadora
-Batería para filmadora
-Zero Hair
-Visas y vacunas
-Pasaporte
-Diccionario japonés
-Aguja e hilo para coser karategi
-Guantes

Gastos:

Traslado desde aeropuerto a Sinbi:  USD 27
Cotizaciones:

1 Dólar = 32 Baht
1 Dólar = 80 Yen

Ubicación del Dojo:

大阪市北区錦町3-1
Google Map: 34.705317, 135.512967

Hotel   APA TEMMA**
Google Map: 34.703853,135.51669


Recorrido desde el dojo al hotel:

http://maps.google.com/maps?saddr=Jap%C3%B3n+%C5%8Csaka-fu,+%C5%8Csaka-shi,+Kita-ku,+Nishikich%C5%8D,+%EF%BC%93%E2%88%92%EF%BC%91&daddr=+34.703853,135.51669&hl=es&ie=UTF8&ll=34.704263,135.514839&spn=0.00258,0.004823&sll=34.704585,135.515993&sspn=0.00516,0.009645&geocode=Ff-OEQIddsMTCCnfYYECx-YAYDGdjJfc3jPmYg%3BFe2JEQIdEtITCA&t=h&ttype=now&noexp=0&noal=0&sort=def&mra=ls&z=18&start=0


PRECIO POR HABITACIÓN POR NOCHE EN DOBLE USD  178,00

Categoría: 2 Estrellas
Dirección: 2-16-15 DOUSHIN KITA-KU

Localización: En ciudad
C.P.: 5300035
Población: OSAKA
Provincia: --
País: JAPÓN