Show Posts
Pages: 1 2 [3] 4 5 ... 358
31  Using Arduino / Programming Questions / Re: multiple if or for loop with if inside on: July 28, 2014, 12:47:31 am
thanks. I'm fine with the performance, but I was wondering because I wanted to optimize a part of my sketch, just because it's a bunch of ugly and LARGE if. It's a slighty different approach than that one. Here it goes, tell me what you think


Code:
if(array[15] == HIGH){
counterTest = 14;
}
if(array[15] == HIGH && array[14] == HIGH){
counterTest = 13;
}
if(array[15] == HIGH && array[14] == HIGH && array[13] == HIGH){
counterTest = 12;
}
... and so on until I have an inmensely big conditional.
I needed to know which buttons are high from right to left(in the array) only when they are consequent. I didn't like that part of the code(but it was the first fix it came to mind) so tonight I made it "better" this way:

That's probably an unneccesary mess. Are the values in array[] other than 0 or 1?

Suppose that you wanted to make array bigger or smaller?

Quote
Code:
for(int i = 15; i >= 0; i--){ //scans the 16 buttons from higher to lower
     if(array[i] == LOW){  // from higher to lower, if it finds a button low, make the counterTest stop summing up
       stop = HIGH;
     
     }
     if(array[i] == HIGH){ //if it finds any that's high, increments the counter
       if(stop == LOW){
       counterTest++;
       }
     }
   }
stop = LOW; //reset the variables
counterTest = 0;
I like way better the latter code, and it may help me optimize other parts of the code with that counterTest value. But, in that case i'm running 2 if inside a for of 16 loops, so it's like 32 ifs..

Have you learned about else or break?
Code:
     if(array[i] == LOW)  // from higher to lower, if it finds a button low, make the counterTest stop summing up
     {
       stop = HIGH;  // if you don't need this after the loop then break takes care
       break; // will exit the loop
     }
     else //if it's not LOW then it has to be HIGH, if LOW else HIGH
     {
       counterTest++;
     }

If you read your digital pins that can only be LOW/HIGH (as 0/1) into the bits of an unsigned int then it becomes much much easier/faster to tell all kinds of things about the states of the buttons and relationships between them.

Bit math understanding will let you write powerful and fast code. Bit logic does all the bits in one command, few to one cycle depending on 8 or 16 bits and what's already in the CPU registers.  It can take days to weeks to get comfortable with but so can driving a car.

http://playground.arduino.cc/Code/BitMath
32  Using Arduino / Audio / Re: Arduino library for WTV020-SD-16P audio module on: July 27, 2014, 03:08:40 pm
I know what you mean about the confusion.
A little extra time in initialization hardly impacts speed anyway.
33  Using Arduino / Audio / Re: Arduino library for WTV020-SD-16P audio module on: July 27, 2014, 09:02:29 am
It might be better to watch the busy pin than to delay and assume readiness.
Best case with the delay is you wait every time longer than needed.
34  Community / Bar Sport / Re: Something for the new and not new programmers. on: July 27, 2014, 08:57:43 am
Me too. It's cheap version control and it keeps a history.
I am starting to write-protect anything I am not working on.
35  Using Arduino / Programming Questions / Re: Changing modes question with SMlib on: July 27, 2014, 08:45:00 am
Sensor values are in arrays with count.

Code:
const byte thermometers = 3;
DeviceAddress Thermometer[ thermometers ];
int temperature[ thermometers ];

Add a sensor, change the value of thermometers and it should work.

Perhaps serial prints should all start with the value of millis() to make a proper log.
I think I should add a RAM check command to the serial section, just to keep an eye on that too.

Maybe the longer time is because the 4th sensor is not set up in setup(). Something else to check.
36  Using Arduino / Programming Questions / Re: Changing modes question with SMlib on: July 27, 2014, 08:00:31 am
I updated the change to my copy, also moved Address back 1 space.

The sensor reads are happening 30 seconds apart now?

If so and no other issues there is GSM and LCD parts and then buttons and more sensors?
I am not ready to dive into those right now.
Maybe the sketch needs a long run test anyway just to make sure there is no "down the road" bug(s).

Do you see how I got rid of the delays, using state machines and time checks?

The sensor requests take almost 1/10th second. If all they do is hold up noticing a button or serial then I don't think it's a big deal, much as I don't like it on principle. Maybe the library needs a state machine and time or other check, like answer on the 1-wire bus, too.

37  Using Arduino / Programming Questions / Re: Changing modes question with SMlib on: July 27, 2014, 07:38:05 am
Try this:

Code:

// SIMlib mode change as event code 7-27-14 rev 1

#include <OneWire.h>
#include <DallasTemperature.h>

#include <string.h>

// user serial i/o defines
const byte serialLen = 50;
char serialChar, serialData[ serialLen ];
byte serialCount, serialState; // default of every declared variable is 0
// end user serial i/o defines

char gsmMsg[ serialLen ] = "test GSM message";

// sensor defines
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire( ONE_WIRE_BUS );
DallasTemperature sensors( &oneWire );
// arrays to hold device addresses
const byte thermometers = 3;
DeviceAddress Thermometer[ thermometers ];
int temperature[ thermometers ];
unsigned long sensorsTimerStart, sensorsTimerWait;

byte  readSensorsState, readSensor;
// end sensor defines


const int ledPin =  8;

//================================================SETUP

void setup( )
{
  pinMode( ledPin, OUTPUT );
  Serial.begin( 115200 );

  // sensor setup
  sensors.begin();
  // locate devices on the bus
  Serial.print( F( "Locating devices..." ));
  Serial.print( F( "Found " ));
  Serial.print( sensors.getDeviceCount(), DEC );
  Serial.println( F( " devices." ));

  // report parasite power requirements
  Serial.print( F( "Parasite power is: " ));
  if ( sensors.isParasitePowerMode() )
  {
    Serial.println( F( "ON" ));
  }
  else
  {
    Serial.println( F( "OFF" ));
  }

  oneWire.reset_search();

  byte f = 0; // this will flag if any devices are 'missing'.
  for ( byte i = 0; i < thermometers; i++ )
  {
    if (!oneWire.search( Thermometer[ i ] ))
    {
      Serial.print( F( "Unable to find address for Thermometer " ));
      Serial.println( i );

      // BIG QUESTION HERE -- what to do about the unfound sensors?
      // Answer is stop sketch and have the user fix them.
      f = 1;
    }
    else
    {
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( "  Address: " ));
      printAddress( Thermometer[ i ] );
      Serial.println();

      // set the resolution to 9 bit
      sensors.setResolution(Thermometer[ i ], TEMPERATURE_PRECISION );
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( " Resolution: " ));
      Serial.println( sensors.getResolution( Thermometer[ i ] ), DEC );
      Serial.println();
    }
  }
  if ( f )
  {
    Serial.println( "\nFix the unfound sensors please!\n" );
    while ( 1 ); // halts the sketch
  }
  // end sensor setup

  sensorsTimeStart = millis();
  sensorsTimerWait = 1000UL;

}

//================================================FUNCTIONS

inline void hwSerialRead( )
{
  switch ( serialState )
  {

  case 0 :

    if ( Serial.available( ))
    {           
      serialChar = Serial.read( );

      if (( serialChar == '\n' ) || ( serialCount == serialLen - 1 )) // end of line
      {
        serialState = 10;
      }
      else
      {
        serialData[ serialCount++ ] = serialChar;
      }
    }
    break;

  case 10 :

    if( !strcmp( serialData, "/END" ))
    {
      //      serialData[ 0 ] = 0x1a; // -- 0x1A is what gets sent to gsm
      Serial.println( F( "_" )); // for now, print to monitor
    }
    //Send a saved AT command using serial port.
    else if( !strcmp( serialData, "TEST" ))
    {
      Serial.println( F( " SIGNAL QUALITY " ));
      //     gsm.SimpleWriteln("AT+CSQ");
    }
    //Read last message saved.
    else if( !strcmp( serialData, "MSG" ))
    {
      Serial.println( gsmMsg );
    }
    else
    {
      Serial.println( serialData );
      //     gsm.SimpleWriteln( serialData );
    }   

    memset( serialData, 0, serialLen );
    serialCount = 0;
    serialState = 0;

    break;
  }
}

// sensor functions

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(F("Temp C: "));
  Serial.print(tempC);
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print(F("Resolution: "));
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();   
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print(F("Device Address: "));
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();


// read sensors
// byte  readSensorsState, readSensor;
// unsigned long sensorsTimerStart, sensorsTimerWait;

inline void readSensorsToSerial( )
{
  switch ( readSensorsState )
  {

  case 0 : // REQUEST READ TEMPERATURE
    if ( millis() - sensorsTimerStart >= sensorsTimerWait )
    {
      Serial.print( F( "Requesting temperatures..." ));
      sensorsTimerStart = millis();
      sensors.requestTemperatures(); // how long does this take???
      sensorsTimerStart = millis() - sensorsTimerStart;
      Serial.print( F( "DONE -- request ms " ));
      Serial.println( sensorsTimerStart );
      Serial.print( F("\nTemperatures are " ));
      sensorsTimerStart = millis();
      sensorsTimerWait = 100UL;
      readSensor = 0;
      readSensorsState = 20;
    }
    break;

  case 20 : //  READ TEMPERATURE
    if ( millis() - sensorsTimerStart >= sensorsTimerWait )
    {
      temperature[ readSensor ] = ( sensors.getTempC( Thermometer[ readSensor ] ));
      Serial.print( temperature[ readSensor ] );
      Serial.print( F( " Celsius" ));
      if ( readSensor < thermometers - 1 )
      {
        Serial.print( F(", "));
        readSensor++;
      }
      else
      {
        Serial.print( F("\n\n"));
        readSensor = 0;
        //        lcd.clear();
        //        readSensorsState = 30;
        readSensorsState = 0;
        sensorsTimerWait = 30000UL; // next read in 30 seconds
      }
      sensorsTimerStart = millis();
    }
    break;

    /*           uncomment when the LCD is added
     case 30 :
     if ( readSensor < thermometers )
     {
     lcd.setCursor( 0, readSensor );
     lcd.print( F( "T" ));
     lcd.print( readSensor );
     lcd.print( F( ":   C" ));
     lcd.setCursor( 3, readSensor );
     lcd.print( temp[ readSensor ] );
     readSensor++;
     }
     else
     {
     readSensor = 0;
     readSensorsState = 0;
     }
     break;
     */

  }
}

// end sensor functions


//================================================LOOP

void loop()
{
  hwSerialRead( );
 
  if ( millis() - sensorsTimerStart >= sensorsTimerWait )
  {
    readSensorsToSerial( );
  }
}

38  Using Arduino / Programming Questions / Re: Changing modes question with SMlib on: July 27, 2014, 07:22:35 am
Did you change the case number in readSensorsToSerial( )?

The first case in the code I posted is 10, should be 0.
There will likely be many readings fast if it works and that will get fixed.



39  Using Arduino / Programming Questions / Re: How to create lookup table on: July 27, 2014, 06:31:25 am
I see. Pre-scaling won't work that way with integers. But I don't pre-scale.

In Forth there is a scaling operator, */, that takes 3 values, multiplies the 1st 2 then divides by the 3rd.
It promotes the values to double-word (16 bit to 32 bit) and returns a single word, all integers.

When step 1 is to multiply what is to be scaled by the scaler numerator, it's okay if the denominator is bigger.

40  Using Arduino / Programming Questions / Re: Changing modes question with SMlib on: July 27, 2014, 05:30:43 am
It's untested code.

Change the case 10 to case 0
Code:
inline void readSensorsToSerial( )
{
  switch ( readSensorsState )
  {

  case 10 : // REQUEST READ TEMPERATURE

Enter a bunch of random text into serial monitor.
When you enter a non-command, it prints the text. So if you don't enter a printable character, you see nothing.
Serial commands are MSG, TEST and /END. Try those.

If serial is still not working ........... add a line right after this
Code:
inline void hwSerialRead( )
{
  switch ( serialState )
  {

  case 0 :

    if ( Serial.available( ))
    {           
      serialChar = Serial.read( );


Code:
Serial.print( serialChar );

It will make a mess of the screen if hwSerialRead( ) runs and text characters are entered but it should confirm serial reads are made.

41  Using Arduino / Programming Questions / Re: Set bits in a variable as output ports for serial connections on: July 27, 2014, 01:14:09 am
This is where the Arduino Foundations link to Functions and the Sheepdog's link to Functions that return a value comes in. The concepts are better explained in those than there is room for here. Study those and you won't go away missing pieces that hints and clues here will not cover. And you shot right by those links, didn't you?

This sketch has a function, not just a few lines of code but an actual function named myMultiplyFunction that takes 2 integers, multiplies them and returns the product as the result. The function code does not need to know what variable names the 2 integers are from and the code that uses the function does not need to know what variable name the returned value is in because there isn't any. A variable can be thought of as a function that returns the value at a named address in memory. This is what I mean by fundamentals.

Code:
void setup(){
  Serial.begin(9600);
}

void loop() {
  int i = 2;
  int j = 3;
  int k;

  k = myMultiplyFunction(i, j); // k now contains 6
  Serial.println(k);
  delay(500);
}

int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

You can run with the above but you might go to the source and make sure that you have all the bases covered.
http://arduino.cc/en/Reference/FunctionDeclaration

The link to Sheepdog's site explanation of functions is even better. And yes, there are caveats to know -- we get "why doesn't" questions about them here on a regular basis.

Relax, don't rush, don't play the "never time to do it right, always time to do it over" game that society often teaches. In the not so long run you will come out ahead.
42  Using Arduino / Programming Questions / Re: Buttons and Led's - Button switching too quickly on: July 27, 2014, 12:21:07 am
I don't think you're ready for the code I posted in the other thread because it uses a few concepts that you're not familiar with, don't have the strength of practice in which is OKAY. Nobody starts knowing that much, it takes time and I see you are how long now just knowing about arrays and loops at all let alone working through the implications.

Programming is like a game with simple rules but deep strategies, and there are many of those. The new player starts with the rules and basic play and picks up the strategies by explanation and doing as they go.
The player who doesn't learn half of the rules may be able to play at all but they don't make good choices, miss a lot of opportunities in playing, don't see enough of how it works to understand what goes on to make strategies.
If you learn poker and only know to get as many of the same number card then you could get dealt a straight or a flush and throw it away trying to get just a pair to bet on. It's not your fault per se but it costs, with code the big cost is time spent going down wrong paths instead of learning about paths.
In games people can explain aspects in ways that are sensible but if any part uses a rule the new player just heard of then for the first time, sensible is not enough for knowing. The 'new' rule needs to be demonstrated and used to see how it fits before sensible becomes sense and understanding.
So when you see code with parts that you understand and other parts that are mysteries, stop and work out the mysteries even if it is just to make sure they work as they should.
Code bugs teach that every letter and symbol counts. If there is any that you are not sure of then you don't know, it is time to go back as far as it takes to know and be sure. You might be able to slap parts together and build a little shed but try the same only bigger or just adding changes and it may come crashing down on you, after a lot of work and maybe expense of course! That is why so many technical people have Murphy's Law posters, to remind them that what you or someone else don't know can bite you harder than you would think.

It's not your fault to get lost unless you plow ahead as if you're sure of what you don't know.

Arduino is fast. Not 3 Gz multi-core fast but magnitudes faster on the scales of buttons and most communications than most people, even well past beginner tend to realize. That is one of the big implications that has a major effect on approach, strategy.

What beginners learn is to use delays to stop processing and let events catch up. The delay is "long enough" when the code works. This is what is taught. It is in the beginners examples and many tutorials. With experience a coder can usually trim the delays down and even use fewer delays and artificial delays.

But delays tend to limit the code to a single path however twisted and complex and deeply nested it gets to do the more and more that is desired. The result is almost always what is called spaghetti code, aka the can of worms that every time it is opened takes a bigger can to put the worms back in -- the can is how much RAM, etc, it takes.

Beginner techniques belong in small code even though they can be used to make very big code indeed.
When the code is used for sequential processes, this then that, the only matter is how much will it take.

When you start dealing with events that need to happen when they are ready, it is time to learn new ways with new ideas and terms like asynchronous and synchronous.
Synchronous is like on time, in order, in step like a military parade.
Asynchronous is when it happens, if it happens, order only as needed, on different paths as needed.
(There is more usually halfway, like a marching band all in ordered step but everyone plays their own music.)

If you want to do many things at once smoothly then you don't have code that holds everything up just because one thing isn't ready. You can do that and it can work when there are only a few things going on but it is klunky and gets klunkier with everything added.
For a button and a led and maybe serial input, go ahead but with 16 buttons and as many led strips the only "works" will involve a user who has to be careful with the buttons and accepting push, hold and wait operation. And that brings it around to what you want, what you can accept, how you get there and when.

You can practice and learn on smaller sketches, step by step, or you can plow onward with what you know.
My choice would be the former and the above is my explanation of why.

43  Using Arduino / Programming Questions / Re: Set bits in a variable as output ports for serial connections on: July 26, 2014, 04:56:36 pm
Now immagine I would print everything into the LCD in a single operation. Lets say that would take me 100ms. During those 100ms the CPU would be busy and other important tasks would not be completed.

100ms is 1,600,000 cycles, a long time to Arduino. Even 1ms is enough to do > 1 useful processes.
100ms is also fast enough to be difficult for human eyes to keep up with much of.

Have you learned BlinkWithoutDelay?


44  Using Arduino / Programming Questions / Re: Set bits in a variable as output ports for serial connections on: July 26, 2014, 04:43:51 pm
Quote
I want to run the SPI print function once in the loop.
And I want the data to be sent (each time a bit changes) to wait for the loop to be executed again, rather than simply make the change as in the code below. this will give priority to the loop, rather than the LCD output.

Does this make sense? If not please feel free to ask

What you outline is how I handle multiple buttons, leds, etc. But your details don't show it.
I think that you need to spend time learning some fundamentals at the working level.

Maybe a **small short** example printing to serial monitor instead of SPI would help you organize your thoughts.
Let the text be labeled "SPI transfer: " and print hex values, leading zeros or not.
By the time you have that right, you will be able to communicate much more concretely, ask better questions.

I have done those things and it didn't happen right away, I can tell you. I cracked books and wrote code just so I could learn what I was doing. Even if you have a teacher, without practice the lessons are empty. Take your time and you will improve, rush and you will forget as soon as the next part comes along.





45  Using Arduino / Programming Questions / Re: Set bits in a variable as output ports for serial connections on: July 26, 2014, 01:39:26 pm
Okay. What you put inside the code tags in the last 2 posts makes no sense to me at all.

You send some data out through SPI then change a bit in the data, wait, and change it again and wait.
Why? I have no clue. Those changes aren't going anywhere, certainly not to SPI.

Code:
digitalWrite (csPin, LOW); // connects to RCLK

SPI.transfer (lowByte (data)); // send out lower 8 bits
SPI.transfer (highByte (data)); // send out upper 8 bits MSB first
digitalWrite (csPin, HIGH); // data output changes on this rising edge


bitSet(data, 3);
delay(500);
bitClear(data, 3);
delay(500);
Pages: 1 2 [3] 4 5 ... 358