Go Down

Topic: Deep Think Project - Artificial Intelligence Research Project (Read 22565 times) previous topic - next topic

ShapeShifter

What if you haven't used it in a while?
The way the loop is written, that isn't likely to happen - there are much bigger issues with the current structure.

As it is, loop() will get called frequently. In each pass, the robot will start to raise both arms, then it will start checking whether the time has expired. Most of the time this will be false, and all of the if statements will skip their processing, and the loop will quickly exit and start over (by immediately starting to raise arms again.) finally, the time will expire, but it's impossible to predict which if statement will return first - it's pure random chance where the code will be at when millis() finally returns the target time.

The net result is that on each loop the robot will start to raise it's arms, and then every two seconds it will randomly do some other operation, but then immediately go back to the top of the loop and raise the arms again. I predict the externally visible result will be a robot that raises both arms, and then every two seconds makes a brief buzz or click as it starts to do something else and then immediately goes back to raising the arms. Or at least that's what the arm servos will do - if it happens to hit a command that tries to lower them, it will once again raise them so quickly they might not even have time to move. I don't know enough about the robot's details to know if other motors will do anything - they may do nothing, or may operate erratically or randomly.

I said that which function will trigger is completely random: that's not quite true. The odds are somewhat in favor of the first if statement, the one that puts down the arms. That's because the window of opportunity for the time to change between each if statement is small, since they are one after each other. However, after the last if statement, there is the time it takes to return from the function, loop around, re-enter the function, call the raise arms functions, and set TimeNeeded. This will all be fast, but will still take more time than evaluating each if condition - since it spends more time before this if condition than the others, there is a rather chance that millis() will hit the target time then, so the window of opportunity is larger for that first if. So the odds are higher that it will be that one that periodically triggers.

Having a bunch of delay() calls in a program like this is generally a bad idea. But using this method of timing is FAR worse!

The issue is not that delay() is inherently evil - the real problem is writing a loop() function that does a long process step by step and doesn't return until the whole sequence is done. That's what causes problems - delay() is just an easy way to make such a long blocking sequence: it's a symptom, not the disease. By re-writing delay into a Time() function, you are not solving the root problem.

Goodinventor: this is a good learning opportunity, and you should take some time to research "finite state machines" - that will be a necessary component to getting this to work properly, much more valuable than simply rewriting delay() or using multiple processors.

goodinventor

Robin2: Perhaps I have not made myself clear on what I am currently trying to do. I am not trying to do something out of my reach. At the moment the hardware is just a little beyond my current knowledge. I need to learn a little more about finite state machines to control my robot in a simple, predictable way, I need to learn how to control servos (which I recently did), and I need to learn about a few of the basic I/O protocols (SPI, UART, I2C, and CAN). The robot at the moment is only a little more complex than a basic wheeled robot.

jremington

Quote
I am not trying to do something out of my reach.
Then why did you choose the rather bold title of this thread to be "Artificial Intelligence Research Project"?

Many very smart people having been working on similarly titled projects, in large groups, for several decades now, with computers many orders of magnitude more powerful than an Arduino.

And despite Steven Hawking's dire predictions, artificial intelligence doesn't seem to be a gleam in anyone's eye, let alone a pressing threat.

goodinventor

ShapeShifter: All right, so basically my logic within loop() is all wrong. Are there any issues in the Time() function itself. I looked hard at the code for BWoD, but I cannot see a clear way to fix my code.

goodinventor

That is the title because that is the point of this project. What I am doing now is just a step towards that end. Also, the board I am using is Arduino compatible, but it does not have an ATmega chip. Instead it has an x86 processor (full 586 instructions) with 128MB of RAM and 8MB of Flash built in. It also has a microSD card slot that supports up to 32GB. This is somewhat stronger than a typical Arduino.

Frostline

Here's a simple challenge I propose to people who think they've fully grasped the BWOD Principle, and you can do it on a bare Arduino: make the LED on pin 13 fade up down, without using delay.
For bonus marks, add a potentiometer and vary the fade rate.
You have video of that LED fading?
After over a hour of fussing with it I tried the fade example in the IDE and it just blinked.
Fades fine on say an LED on pin 9 for example but no visible fading but just blinking on pin 13.
Tried on both an Uno and Nano (both clones though).

Delta_G

just blinking on pin 13.
Awfully hard to fade an LED on a pin that's not capable of PWM.

|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Frostline

Awfully hard to fade an LED on a pin that's not capable of PWM.


Probably so.
I was just following instructions as given not thinking a mod would ask an impossible task.
I did get my fade without delay to work on pin 9 and enjoyed the challenge. 

 Was 40+ lines of code. Would like to see the around 20 line version eventually.

Word of caution to other novices like me. Either use big steps or keep to the low end of the pot. For awile I thought my code didn't work until I realized doing some math on the values I was using the fade was going to take about 36 hours.

Delta_G

I was just following instructions as given not thinking a mod would ask an impossible task.
It's not impossible.  You just can't use analogWrite to do it.  You have to flicker the led yourself.  That's the challenge.
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

RayLivingston

Awfully hard to fade an LED on a pin that's not capable of PWM.


Actually, no.  It's not hard at all.

Regards,
Ray L.

GoForSmoke

ShapeShifter: All right, so basically my logic within loop() is all wrong. Are there any issues in the Time() function itself. I looked hard at the code for BWoD, but I cannot see a clear way to fix my code.
If you don't see why that single Time() function can't work for multiple events then you need to quit fooling yourself, you have more than a little to learn about code and you are in way over your head.

Nick Gammon has tutorials that can get you started on "many things at once" and finite state machines. They're simple, complete commonsense explanations with the whys as well as the hows and whats. The addresses are in my signature space at the bottom of my post.

Learn how it works and you can know more about what doesn't work and why. At that stage you don't have to discover every mistake the hard way.

You know what Newton said about seeing farther? The giant to stand on is the work already done. Climb that and then set your sights.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

GoForSmoke

Awfully hard to fade an LED on a pin that's not capable of PWM.


Not at all. Human eyes are slow and Arduino is fast.

The code is BWOD with uneven and always-changing intervals at heart.

Consider that PWM is about 500Hz by default. If your total ON/OFF time always takes 2ms, the eye will be fooled, a 5 ms frame should work fine too.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

MorganS

Yes, I was forgetting that you don't have PWM on pin 13 on most Arduinos. Without analogWrite(), my solution is a bit longer than I boasted: 35 lines with comments and blank lines included.

Of course everyone's interpretation of "Fade an LED" is different. Frostline seems to be using a pot, like the AnalogInput example. My interpretation was more like the Fade example from the 01.Basics menu or the Fading example from the 03.Analog menu. [Why are there two examples almost identical?]
"The problem is in the code you didn't post."

GoForSmoke

I took more lines than it might need, more than I thought. I could take 4 out right off the top but then changing those constants becomes a pain. It doesn't have to have the slowFade part either but I wanted to slow the fade rate.

FWIW,

Code: [Select]

const int ledPin =  13;
byte ledState = LOW;

char stepDirection = 1;
unsigned long stepNumber = 0;
const unsigned long totalSteps = 500;

byte slowFadeCount;
const byte slowFadeFactor = 2;

unsigned long startMicros;
unsigned long waitMicros;
const unsigned long pwmFrameMicros = 4000;

void setup()
{
  pinMode( ledPin, OUTPUT );
}

void loop()
{
  if ( micros() - startMicros >= waitMicros ) // will run first time
  {
    startMicros = micros();
    ledState ^= 1; // flip bit 0
    digitalWrite( ledPin, ledState );

    if ( ledState )
    {
      waitMicros = ( stepNumber * pwmFrameMicros / totalSteps );
    }
    else
    {
      waitMicros = pwmFrameMicros - waitMicros;
    }

    if ( ++slowFadeCount >= slowFadeFactor )
    {
      slowFadeCount = 0;

      if ( stepDirection > 0 )
      {
        if ( ++stepNumber >= totalSteps )
        {
          stepNumber = totalSteps;
          stepDirection = -1;
        }
      }
      else
      {
        if ( --stepNumber < 1 )
        {
          stepNumber = 0;
          stepDirection = 1;
        }
      }
    }
  }
}

1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

AWOL

If pin 13 were hardware PWM-capable, it wouldn't have been a challenge, would it?  ;)

Go Up