Connect with us

New guy basic help

Discussion in 'Microcontrollers, Programming and IoT' started by Jabmel, Jul 21, 2013.

Scroll to continue with content
  1. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Hi all. Thanks for letting me join

    I am building a new n gauge train set and want to use some development boards to control my signalling

    I have found some at mega64 boards and ARDUINO compatible ones. The issue is my pascal or c+ is not good to nil. However I am really good with ladder logic and can use LD Micro. This is comparable with amtel mega chips. And compiles to ASCII I think

    I would like to use a few AMTEL AVR ATMEGA168A or AMTEL ATMEGA64at development boards to receive digital inputs or drive LED outputs. Can these still be programmed by LD Micro or do I need to learn ARDUINO

    What other interface is needed to talk to these above boards as there is no USB on board

    Alternately any recommendations. Thanks again. Ben.
     
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,497
    2,838
    Jan 21, 2010
    I think the short answer is "learn C"

    I feel your pain, because C is pretty poor at quite a few things that other languages make really easy. Fortunately those things are not the sort of thing you'll need to do very often when programming a microcontroller.

    There are plenty of examples with the Arduino environment and it really is as easy to learn as C is ever going to be.
     
  3. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Thanks steve. Looking to do a whole heap of and and or calculations from 150 inputs across 6 development boards. A lot of the YouTube vids want to show me how to blink an led or move on quickly to motors and such. Any leads or links that focus on and or nor etc. thanks ben.
     
  4. sirch

    sirch

    109
    1
    Dec 6, 2012
  5. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Thanks guys. I have found the information relating to using logic gates in arduino. Last part of the puzzle is the (internal relay or coil) that can be assigned in the ladder logic. Ie an internal input/output. For example

    How would you write the below (this is a basic example) if you had multiple inputs that gave you a condition that was re used in many other functions you would assign an internal relay bit. Contacts from this bit could be introduced into other rungs to drive outputs

    ((A and B) or C) = D

    A= input
    b= input
    C= input and
    Z = output (ie led)

    An internal bit ( relay coil logic ) (d)

    ----(a)----(b)----------------------(d)---
    |__(c)____|

    ----(d)-----------------------------(z)------

    Thanks ben.
     
  6. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    If you're coming from a ladder logic background, the thing you need to understand is that I/O ports don't change state unless your code tells them to. So you can't simply define a particular output pin as being a logical combination of several input pins; you have to write code to continuously scan the inputs, calculate the appropriate output state, and update the output pin.

    Your description seems to use 'D' as equivalent to 'Z', the output that controls the LED. You can skip this extra step and avoid having any variable called D.

    The MCU runs continuously (unless you use a sleep mode), constantly processing instructions and acting on them. So you will need to use some kind of loop to tell it to repeat the calculations continuously.

    Code:
    #define input_A PA3 // the port pin called PA3 will be used as input_A
    #define input_B PA4 // the port pin called PA4 will be used as input_B
    #define input_C PA5 // (choose these port names to suit your hardware connections.)
    #define output PA1
    
    void main(void) { // every program needs a function called main(); it is called at startup.
        // At this point, you need to configure various control registers in the MCU.
        // At a minimum, you need to configure the "data direction registers" for the ports
        // you will be using, to tell the MCU which pins should be inputs and which
        // pins you want to use as outputs. For the small PIC devices, this is controlled
        // by registers called TRISx, I think. Setting bits in those registers puts the
        // corresponding port bit into "tri-state" mode, so it can be used as an input.
        // Otherwise, the port pin is an output.
        TRISA = 0x38; // 0x38 = 0011 1000 binary; configures PA3, PA4 and PA5 as inputs
        while (1) { // repeat this loop (between the squiggly brackets) forever
            if ((input_A && input_B) || input_C)
                output = 1;
            else
                output = 0;
            } // end of while(1) loop
        } // end of main() function
    That's the general idea. I'm not sure about the TRISA part - I don't use PICs myself. The register name and details may be wrong. Have a good read of the data sheet for the device you choose, and if you have any specific questions, ask them here.

    The #define statement is not normally used to define single-bit quantities but I believe the PIC compiler supports this.
     
  7. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Thanks kris. All these bits are helping me to convert. I use the bit "d" in the ladder logic to save writing the condition again. It may be in other rugs tied with other inputs. Ie saves time and space. Ie

    --------(d)----------(x)------------------(y)

    I don't need to write (((a&b)or c)&x)=y


    I can use the substitute bit d already defined as an internal relay bit
    (d&x)=y

    Thanks all this is great getting the feed back. Cheers ben
     
  8. sirch

    sirch

    109
    1
    Dec 6, 2012
    So in Arduino land you could do something like

    Code:
    #define A 4; //A is digital pin 4
    #define B 5; 
    #define C 6; 
    #define Z 7;
    
    void setup()
    {
      pinMode(Z, OUTPUT);      // sets the digital pin 7 as output
      pinMode(A, INPUT);      // sets the digital pin 4 as input
      pinMode(B, INPUT);      // sets the digital pin 5 as input
      pinMode(C, INPUT);      // sets the digital pin 6 as input
    }
    
    void loop()
    {
      int a = digitalRead(A);
      int b = digitalRead(B);
      int c = digitalRead(C);
    
      boolean d = (a && b) || c;
    
      if(d) {
        digitalWrite(Z, HIGH);
      }
    }
    

    There could be errors in that, I haven't tried compiling it.
     
  9. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    sirch, your code also needs to take an action if d is zero. As it stands, it can only set the output pin high, not low. You can either unconditionally say digitalWrite(Z, d); or use the if-else arrangement that I used in my example.

    Also you need some code to call your 'loop()' function repeatedly. (I would not call a function loop()!)
     
  10. sirch

    sirch

    109
    1
    Dec 6, 2012
    In Arduino, for better or for worse, the "setup" function is called once at startup and the "loop" function is called repeatedly. I didn't make up the names...

    My example was not intented to be a complete solution, merely to address the OPs question about storing the result of ((a and b) or c)
     
  11. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,497
    2,838
    Jan 21, 2010
    I would change

    Code:
    if (d) {     
      digitalWrite(Z, HIGH);   
    }
    to

    Code:
    digitalWrite(Z, d);
     
  12. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    Oh, I see!
     
  13. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Sweet guys. I will give this a go and see what I get. I will re post the 1 st part for comments before I attempt the complete program. Cheers again. Ben.
     
  14. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    ok guys, i bit the bullet

    I have got a development board set and had a play, this is my first program and works great, can you have a look and see if it could be slimed down (simplified)

    this is for 2 switches and 6 leds, once complete the trainset will be 30 switches, 8 AUX digital inputs and 100 leds (signals) across 8-10 mega boards, so if i am doubling up here with code and don't need to i would like to know now

    sw101 and sw102 are switches (points)

    led's are signals
    ledb"X" (b set red and green)
    leda"X" (a set green and Yellow)
    ledc"X" (c Set red and green)

    this is a basic control for 2 switches and 3 train light signals

    ben

    *******************************

    const int sw101Pin = 1;
    const int sw102Pin = 2;
    const int ledbgPin = 3;
    const int ledbrPin = 4;
    const int ledayPin = 5;
    const int ledagPin = 6;
    const int ledcrPin = 7;
    const int ledcgPin = 8;


    int sw101State = 0;
    int sw102State = 0;
    void setup() {

    pinMode(ledbgPin, OUTPUT);
    pinMode(ledbrPin, OUTPUT);
    pinMode(ledayPin, OUTPUT);
    pinMode(ledagPin, OUTPUT);
    pinMode(ledcrPin, OUTPUT);
    pinMode(ledcgPin, OUTPUT);
    pinMode(sw101Pin, INPUT);
    pinMode(sw102Pin, INPUT);
    }

    void loop(){
    sw101State = digitalRead(sw101Pin);
    sw102State = digitalRead(sw102Pin);


    if ((sw101State == HIGH && sw102State == HIGH) || (sw101State == HIGH && sw102State == LOW))
    {
    digitalWrite(ledagPin, HIGH);
    digitalWrite (ledayPin, LOW);
    digitalWrite (ledbgPin, LOW);
    digitalWrite (ledbrPin, HIGH);
    digitalWrite (ledcgPin, LOW);
    digitalWrite (ledcrPin, HIGH); }


    if (sw101State == LOW && sw102State == HIGH) {

    digitalWrite(ledagPin, LOW);
    digitalWrite (ledayPin, HIGH);
    digitalWrite (ledbgPin, LOW);
    digitalWrite (ledbrPin, HIGH);
    digitalWrite (ledcgPin, HIGH);
    digitalWrite (ledcrPin, LOW); }


    if (sw101State == LOW && sw102State== LOW){

    digitalWrite(ledagPin, LOW);
    digitalWrite (ledayPin, HIGH);
    digitalWrite (ledbgPin, HIGH);
    digitalWrite (ledbrPin, LOW);
    digitalWrite (ledcgPin, LOW);
    digitalWrite (ledcrPin, HIGH);}
    }
     
  15. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,497
    2,838
    Jan 21, 2010
    There are ways to control many LEDs from a single arduino, and also ways to read many more inputs.

    However, given the price of an ATMega8 chip, and the ability to run it without a crystal, it almost makes sense to have multiple ATMega8 chips, with each performing a simple set of functions.

    Well, it makes sense unless you want them to be integrated. If the lights just show the position of points, and whether there's a train on a section of track, that's OK. If you want to use it to actually control the train(s) as well, at least one chip needs to know the state of every set of points and signal lights.

    The advantage of directly connecting things to the chip is also that the code is *very* simple (as you've demonstrated above).

    However, you can rewrite your code as follows:

    Code:
      if (sw101State == HIGH)
      {       
        digitalWrite (ledagPin, HIGH); 
        digitalWrite (ledayPin, LOW);
        digitalWrite (ledbgPin, LOW);
        digitalWrite (ledbrPin, HIGH);
        digitalWrite (ledcgPin, LOW);
        digitalWrite (ledcrPin, HIGH); 
      } else {
        if (sw102State == HIGH) 
        {
          digitalWrite (ledagPin, LOW); 
          digitalWrite (ledayPin, HIGH);
          digitalWrite (ledbgPin, LOW);
          digitalWrite (ledbrPin, HIGH);
          digitalWrite (ledcgPin, HIGH);
          digitalWrite (ledcrPin, LOW);  
        } else {
          digitalWrite (ledagPin, LOW); 
          digitalWrite (ledayPin, HIGH);
          digitalWrite (ledbgPin, HIGH);
          digitalWrite (ledbrPin, LOW);
          digitalWrite (ledcgPin, LOW);
          digitalWrite (ledcrPin, HIGH);}
        }     
      }
    
    In some respects, it might be cleaner to write something like this:

    Code:
      digitalWrite (ledagPin, sw101State); 
      digitalWrite (ledayPin, !sw101State);
      digitalWrite (ledbgPin, (!sw101State) && (!sw102State));
      digitalWrite (ledbrPin, sw101State || sw102State);
      digitalWrite (ledcgPin, (!sw101State) || sw102State);
      digitalWrite (ledcrPin, sw101State || (!sw102State)); 
    
    the third one can be re-written in a way that may be more clear as well...

    Code:
      digitalWrite (ledbgPin, !(sw101State || sw102State));
    
    When written like this, it is also more obvious how the signals relate to each other.
     
  16. Jabmel

    Jabmel

    8
    0
    Jul 21, 2013
    Thanks steve

    I think I get the gist and the second example you list looks the best for what I want to archive.

    Can you give me a bit more in relation to that the code means. I think I under stand it as

    The digitalwrite for the given output is made by "matching" the state of the digital input. Ie

    "Basic example only here"

    LedA, LedB - inputA, InputB

    DigitalWrite (ledaPin, inputA)

    LedA will be high if inputA is high, if not then it will stay low

    DigiatalWrite (ledbPin, (inputA && inputB))

    LedB will be high if inputA and inputB are high, if not it will stay low

    Or

    DigitalWrite (ledbPin, (inputA || ! InputB))

    LedB will be high if inputA is high or inputB is low, if not will stay low

    Thanks ben.
     
  17. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,497
    2,838
    Jan 21, 2010
    Well, let's assume that High = true = On.

    (It is possible that you might equate low to on, in that case you would need to change something -- if you were reading such a value you might invert the value after reading it so that ON = True)

    Well, it is perhaps better to say that the value which is set is the result of the equation.

    Correct, but I would state it as ledApin assumes (or is assigned) the same state as inputA

    There is no "stay low". LedB will be high if inputA and inputB are high, if not it will be low. To have some concept of "stay low" we would need the state to depend on the previous state. In this case it does not. The output state is determined solely by inputA and inputB.

    Same comment as above.

    Also, you could state that the ledbPin is updated to have the state determined by the equation (inputA || !inputB).

    One thing that is important... Do you see the difference between

    !(inputA || inputB)
    and
    ((!inputA) || inputB)

    if so, what does this mean?

    (!inputA || inputB)

    It means one of the examples above, but to know which one you need to be aware of the order of precedence for operators.

    I find it better to explicitly use parentheses in situations like this (as I have in my examples).
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-