0

Question Summary:

It works, but on my specific case I am get into problems due to data encoding. Data is sent through the arduino as "coin" but its printed output in my console application is "2". Then I have the issue of sending the string "1234" from my console application, and not being able to receive it in the arduino. I think the data is being set as a different encoding so that the statement is nos looking for the right information. It is that simple and that complicated. (oh stackoverflow!)

Serial port is open and baud rate is set

Arduino code snippets:

Serial.println('coin');

if( Serial.readString() == "1234"); <<<--- how can i relax this condition as i did in the example below. (it does work on the Serial monitor but not on the software, is it an encoding situation?)

VS code snippets:

SerialPort sp = (SerialPort)sender;

string indata = sp.ReadExisting();

if (indata.Contains("coin"))   <<<---  it is a relaxed contains condition, **works** in my case, since I dont really know excaclty what it is receiving.

SerialPort.Write("1234"); (how do I make sure it receives the characters i send be it ANSI hex or whatever.

thanks for your help.

Start of Regular post

Good afternoon,

I have arduino code:

int ledPin = 13;
const int coinInt = 0;
int incomingByte = 0;

#define RELAY_ON 1
#define RELAY_OFF 0
#define Relay_2  7

int waittime;
volatile int coinsValue = 00;
volatile int coinsChange = 0;       //A Coin has been inserted flag

void setup()   {
  digitalWrite(Relay_2, RELAY_ON);
  pinMode(Relay_2, OUTPUT);  
  delay(1000);

  Serial.begin(9600);                
  attachInterrupt(coinInt, coinInserted, RISING);   //If coinInt goes HIGH (a Pulse), call the coinInserted function
}

void coinInserted()  {
  coinsValue = coinsValue + 01; 
  coinsChange = 1;  //Flag
}

void loop() {
  if(coinsChange == 1)   
  {
    coinsChange = 0;   

   if(coinsValue >= 50)   {
      Serial.println('coininsertion');
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);    
  }
         if (Serial.available() > 0) {
                incomingByte = Serial.read();
                delay(250);
                digitalWrite(ledPin, LOW);
                digitalWrite(Relay_2, RELAY_ON);

   }                
  }
}

and c# console application code:

using System;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;


class PortDataReceived
{
    public static void Main()
    {
        SerialPort mySerialPort = new SerialPort("COM3");

        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.RtsEnable = true;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();


      Console.WriteLine("Press a key to continue...");
      Console.WriteLine();
      Console.ReadKey();
      mySerialPort.Close();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {

        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
   //     Thread.Sleep(100);
       // Console.Write(indata);
        Thread.Sleep(100);
        if (indata.Contains("coininsertion"))
        {
            Thread.Sleep(100);
            //Process.Start(@"C:\\Users\laptop\Documents\rb_software\print.ahk");
           Process process = new Process();
            // Configure the process using the StartInfo properties.
           process.StartInfo.FileName = @"C:\\Users\laptop\Documents\rb_software\print.ahk";
            //process.StartInfo.Arguments = "-n";
            //process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
           process.Start();
           Thread.Sleep(100);
           process.WaitForExit();
           Thread.Sleep(1000);// Waits here for the process to exit.
           sp.Write("a");

        }

      Console.Write(indata);

    }
}

A relay closes in the arduino code at the very end:

void loop() {
  if(coinsChange == 1)   
  {
    coinsChange = 0;   

   if(coinsValue >= 50)   {
      Serial.println('coininsertion');
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);    
  }
         if (Serial.available() > 0) {
                incomingByte = Serial.read();
                delay(250);
                digitalWrite(ledPin, LOW);
                digitalWrite(Relay_2, RELAY_ON);

   }                
  }
}

Or at least its supposed to close. Since I sent a character over serial connection in my c++ code near the end:

  process.WaitForExit();
               Thread.Sleep(1000);// Waits here for the process to exit.
               sp.Write("a");

Anyhow, I would appreciate if someone could tell me why it is not closing the switch. Namely turning Relay_2 "ON".

That is all. thanks again.

Julio Sitges
  • 17
  • 1
  • 1
  • 7

2 Answers2

0

Main question: is it working if you use Serial Monitor to send that control character?

Notes for Arduino code (sometimes "WTFs"):

  • ledPin, LOW; in setup() and also no pinMode for this pin
  • coinsChange must be volatile too as it's set by ISR handler and checked in loop
  • Forget about: 00, 01, these values are considered as octal. For these values it's not a problem, but if you use something like 0012 it will be 10 in decimal!!
  • I've never seen comments under the commands they belong. You can place them to line before, to same line (after), but it's highly confusing to have them on line under. Lots of them are commenting obvious things - like: Serial.begin(9600); //Start Serial Communication
  • Wrong indentation makes this code hard to read. And it's few lines.
  • waittime is set only once, never used again.
  • Are you sure coin inserted signal is debounced? If not, it'll be counting lot of pulses for one coin insertion.
  • Why are you so inconsistent with pin numbers and other constants? Once it's int, once const int, once #define...
  • if (incomingByte == '97') pick one: == 97 or == 'a' but never '97' as it's a nonsense for a char.

Btw: that C++ code is actually C#

EDIT: you've fixed just few things. But most important no. For example indentation. Also ' is for ONE character. If you want string, you HAVE TO use "some string". And you definitely wan't serial processing outside of block if(coinsChange == 1). After som tidy up:

const int  ledPin = 1;
const int Relay_2 = 7;
const int coinInt = 0; // coin external interrupt no

int  incomingByte = 0;

#define RELAY_ON 1
#define RELAY_OFF 0

int waittime = 1000;

// Volatile as this variable changes any time the Interrupt is triggered
volatile int  coinsValue = 0;  // Set the coinsValue to a Volatile float
volatile int coinsChange = 0;  // A Coin has been inserted flag

void setup()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // -------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_2, RELAY_ON);
  pinMode(Relay_2, OUTPUT);

  delay(1000);

  Serial.begin(9600);

  // Attach coinInt to Interrupt Pin 0 (Digital Pin 2). Pin 3 = Interrpt Pin 1.
  // If coinInt goes HIGH (a Pulse), call the coinInserted function
  // An attachInterrupt will always trigger, even if your using delays
  attachInterrupt(coinInt, coinInserted, RISING);
}

void coinInserted()  // The function that is called every time it recieves a pulse
{
  ++coinsValue;     // As we set the Pulse to represent 5p or 5c we add this to the coinsValue
  coinsChange = 1;  // Flag that there has been a coin inserted
}

void loop()
{
  if(coinsChange == 1) // check if a coin has been Inserted
  {
    coinsChange = 0;   // unflag that a coin has been inserted
    if(coinsValue >= 50)
    {
      Serial.println("coininsertion");
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);
    }
  }

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

    if (incomingByte == 'a') {
      digitalWrite(ledPin, LOW);
      digitalWrite(Relay_2, RELAY_ON);
    }                
  }
}
KIIV
  • 3,534
  • 2
  • 18
  • 23
  • Hi thanks for answering. made a few changes as you suggested, as for the main question you address, I cant make it work using serial monitor. My guess is that the encoding is dirrefent. Will keep on tryiong and post back any changes. - important : (incomingByte == '97') was commented out because it didn´t work, because of the different encoding I guess. anyhow it was working when i commented that line out, but I dont know what made it stop working. I get its flimsy code. but I would like to make it work. – Julio Sitges Aug 30 '16 at 14:00
  • Thank you for your revised answer. Your indentation is great. much easier to read. I have a question though that is at the center of this thread. the control character sent over serial is exactly : sp.Write("a");. check this question out [link](http://stackoverflow.com/questions/31297195/process-start-only-works-when-line-is-misread) if (indata.Contains("a")) should be more appropiate? because as the answer to the linked qquestion suggested there is more stuff being sent over. additionally wich encoding is it on? i send character "a" do I receive hexadecimal ´97´? – Julio Sitges Aug 30 '16 at 14:45
  • You receive character 97 (decimal ASCII value) or more readable is `'a'` – KIIV Aug 30 '16 at 14:50
  • I have to go to the location to test it out. Great many thanks to you, will post back with results. – Julio Sitges Aug 30 '16 at 14:52
  • Hello, I am testing out and indeed i have a couple problems. it is adding more and more pulses without stop. that is something that did not happen before. also i am not getting the code to read the byte correctly since its not activating the RELAY_2 "ON" STATE. – Julio Sitges Aug 30 '16 at 16:21
  • You can try INPUT_PULLUP pinMode for that input. If it's not enough, you have to use sampling (sample every 5ms and if it's active for four samples, it's considered as coin insertion) – KIIV Aug 30 '16 at 18:43
  • INPUT_PULLUP indeed made a difference, although it repeats coin inserted every once in a while like one out of ten tries, I dont know what can be causing this inconsistency, I will reinforce wiring tomorrow see if that makes it better. – Julio Sitges Aug 31 '16 at 00:58
  • I suppose mechanical bouncing is the problem, not wiring. It's a common problem with buttons (and all mechanical contacts). – KIIV Aug 31 '16 at 05:07
  • I have not solved anything yet, whenever I listen for "coin" i get no response but i do when I listen for "c" why is that? sounds like a new question. – Julio Sitges Aug 31 '16 at 23:31
  • I have found that if the character is more than 127 it uses a different encoding. anyhow the probles is solved now, i just had to use single characters instead of lines. – Julio Sitges Sep 01 '16 at 02:17
0

I think for transmitting and receiving Strings, It is better to use String class in arduino. try Serial.readString()

https://www.arduino.cc/en/Serial/ReadString

here is my sample code for checking a password from RX pin

void loop() {
  if (Serial.available() > 0) {  // if the data came

data=Serial.readString();


if( data == "1234") {
  data="";
   digitalWrite(LED, HIGH); // if 0, switch LED on
   Serial.println("LED ON. Press 0 to LED OFF!");
}
 if(data=="0000"){
 data="";
   digitalWrite(LED, LOW);  // if 1, switch LED Off
   Serial.println("LED OFF. Press 1 to LED ON!");  // print message
}
}

I hope it helps you.

Moonlight
  • 232
  • 2
  • 5
  • 18
  • Thanks for the input, I will try to configure it and post back. – Julio Sitges Aug 30 '16 at 18:21
  • I could not include the constant "data"to work with the example you provided. I mayu not be fluent enough to do it myself. but i tried it without the "data" constant and it worked in serial monitor, now i will try it on live. and report back. – Julio Sitges Aug 30 '16 at 23:45
  • Data is a string, define it at the begininig of the code – Moonlight Aug 31 '16 at 07:05
  • It works, but on my specific case I am get into problems due to data encoding. It leaves the arduino as "coin" and its printed output in my console application is "2". Then I have the issue of sending the string "1234" from my console application, and not being able to receive it in the arduino. Your answer has a tight condition (data=="1234") i need to work on that is being sent and received. It is that simple and that complicated. – Julio Sitges Aug 31 '16 at 21:16
  • It works on the serial monitor, but data comes in very differently from the console application over serial. for instance, i will not ever get it to work since i am listening for a tight condition (=="0000") and i am sure it is gettin transcoded in the process, but what i dont know is how to lock on the encoding. – Julio Sitges Aug 31 '16 at 23:30
  • Indeed it works, but I would need to know how the different encodings are used properly. I preferred to use a single character. in my case that was enough, no need to relax the condition as I initially thought.. – Julio Sitges Sep 01 '16 at 02:24