using PWM outputs after setting the value, is there a way to read what was sent?

I am creating a web based interface that needs to show what the Arduino Uno inputs and outputs are currently doing.
for my example below I am using serial to display the PWM value but this will do for simplicity.
can I read from the PWM output what was sent to it.
Note: digitalRead will give me the digital state of a digital output that is set.

thank you for any help you can give.

void setup()
{
  Serial.begin(57600);
  pinMode(11, OUTPUT);
  analogWrite(11, 100);
}

void loop() 
  setPWM();
  int MyPWMVal = analogRead(11); // this doesn't work but it is what i need to do... HOW can I do this  and is it even possible?
  Serial.print("My PWM Value:");
  Serial.println(MyPWMVal);
{
void setPWM(){ // represents special code setting the PWM output to some value
   analogWrite(11, random(0,255);
}

I don't know of any way to do it short of bypassing the Wiring API and working it out yourself from the hardware settings. It would be far simpler for you to just save the analog output value in a variable - a byte array indexed by pin number would be easy to implement.

can I read from the PWM output what was sent to it.

Why? If you put the PWM value into a variable, and only ever write a PWM pin with that variable, you already know what value it's set to.

Serial.println(your PWM variable value goes here?);

lar3ry:
Why? If you put the PWM value into a variable, and only ever write a PWM pin with that variable, you already know what value it's set to.

My goal was to just add an #include WebView and impliment something more aggressive like this:

#include <SPI.h>
#include <UIPEthernet.h>

// Set your own MAC address for the Ethernet module here:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Set your own IP address for the Ethernet module here:
IPAddress ip(192,168,0,50);
EthernetServer server(80);  
// You can access your Arduino server at http://192.168.0.36

void setup()
{
  Serial.begin(57600);
  Serial.println("Started");
  // Start Ethernet connection and web server
  Ethernet.begin(mac, ip);
  server.begin();
  
  pinMode(11, OUTPUT);
  analogWrite(11, 100);
}

void loop() 
{
  char c = ' ';
  char LastC = ' ';
  // Listen for incoming connections
  EthernetClient client = server.available();
  long time = millis();

  if (client) // If a user is connected
  {
    // An HTTP request from the client ends with two end
    // of line characters (\n x2). We'll need code to check
    // for that.
    boolean currentLineIsBlank = true;
    // This flag is used to check if the first end of line character
    // was sent by the client.

    while (client.connected()) // While web client is connected
    {
      if (client.available())
      {
        do{
          LastC = c;
          c = client.read();
          Serial.print(c);
          // Received two end of line characters (\n). Client has finished
          // sending the request. 
          currentLineIsBlank =  LastC == '\n';
        }
        while ( client.connected() && (c != '\n') && (LastC != '\n')); 


        if (client.connected()) 
        {
          // Send a standard HTTP response header

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // Close the connection once the page is fully loaded
          //client.println("Refresh: 2");  // Refresh the page automatically every 2 seconds
          client.println(); // End of HTTP Response header

          // Send HTML page
          client.println("<!DOCTYPE HTML>"); // Start of HTML document
          client.println("<html>"); // Start of HTML code
          client.println("<head><title>Arduino Interface</title>"); // Set page title
          client.println("<script src='http://code.jquery.com/jquery-latest.min.js'></script>"); // get jquery
          client.println("<script src='http://designi.com/arduino.js'></script>"); // get javascript for my arduino
          client.println("</head>"); 
          client.println("<body>"); // Start of HTML body
          client.println("<div id='start'>Place Holder</div>"); // Set Place Holder
          client.println("<div id='Data'>"); // Set Place Holder
          // Output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) 
          {
            int sensorReading = analogRead(analogChannel);
            client.print("<div id='A");
            client.print(analogChannel);
            client.print("'>");
            client.print(sensorReading);
            client.println("</div>");       
          }
          for (int digitalChannel = 0; digitalChannel < 13; digitalChannel++) 
          {
            int sensorReading = digitalRead(digitalChannel);
            client.print("<div id='D");
            client.print(digitalChannel);
            client.print("'>");
            client.print(sensorReading);
            client.println("</div>");       
          }
            
          // Display server uptime
          client.println("<div id='ServerRunMS'");
          client.println(time);
          client.println("</div></div>");
          client.println("</body></html>"); // End of body and HTML page

          break; // End of transmission
        }
      }
    }
    // Give the web browser time to receive the data
    delay(1);

    // Close the connection
    client.stop();
  }
}

this uses jquery, Javascript and a website to retrieve additional code information for the web page that is derived from data from the arduino. I can then use JavaScript to aggressively display the simple data given to the browser. I was hoping to make this as modular as possible. getting all the information from the arduino uno in one sweep without much additional codeing or tweaking. I am greatful for your input into this I will have to re-think my plan on simplicity. Thank you.

I find the use of the word "aggressive" very very strange ... What has aggression got to do with programming (apart from causing mistakes)?

Never mind ...

I wonder are you confusing analogRead() and analogWrite() which have absolutely nothing to do with each other. AnalogRead() uses the ADC to measure a voltage on the relevant pin aanalog pins. AnalogWrite() cause a PWM signal to be generated on the relevant PWM pin.

No matter how your code updates your web page it just needs to send the value that was most recently used with the relevant analogWrite().

...R

Robin2:
I find the use of the word "aggressive" very very strange ... What has aggression got to do with programming (apart from causing mistakes)?

Never mind ...

I was wondering if someone was curious about what I would like to do. I have an Idea to make a simple way to interface with the web using an uno or mega. the trick is to use Jquery on the client side to make the page look pretty (The aggressive part) we all know that memory is at a super premium on the uno and even the mega. but if all i did was tell the client to get jquery:
client.println("");
and get another custom javascript page:
client.println(""); // my code to make things look great and get more information from the uno
Then I can code with these not worrying about memory I can get graphics and use AJAX (a javascript/jquery trick to get information form a web server, uno/mega, without reloading the entire page) to request more data from the UNO/Mega on the fly... See what I mean by aggressive. My ultimate goal is to make a web interface that works with the atmega328p chip (uno) because they are cheep and I can fab my own boards then link it using the HR911105A breakout Ethernet board to a WiFi receiver linked to my wifi roughter inside my house. put that on a tank type robot using H-Bridge motor control and drive it around my yard using my cell phone or other computer form any where in the world. I will be using GPS for position rather than direct control. ping sensors to prevent running into things. and an IP Camera (not linked through the arduino) to see where I am going.

Robin2:
I wonder are you confusing analogRead() and analogWrite() which have absolutely nothing to do with each other. AnalogRead() uses the ADC to measure a voltage on the relevant pin aanalog pins. AnalogWrite() cause a PWM signal to be generated on the relevant PWM pin.

No matter how your code updates your web page it just needs to send the value that was most recently used with the relevant analogWrite().

I am aware of the analogRead's only able to access the ADC. so I went on a search (google) for a way to discover what was sent to the PWM digital output. I couldn't for the life of me find any code to do such so I posted here. I new that there were far better programmers than me. and I quickly got my answer. "difficult" I am sure there is some memory location that is storing that but no quick way to peek at it. I can understand that, so I will have to add more lines of code to store the data probably create a simple function that stores the value before it is handed to the PWM analogWright() funciton.

Thanks again :slight_smile:

I am sure there is some memory location that is storing that but no quick way to peek at it

There isn't, unless you include registers in your definition of memory locations.

I am aware of the analogRead's only able to access the DAC.

sp. "ADC"

STUFF DELETED

Sorry folks, my internet connection went down and I didn't realize this post was received by the Forum so I wrote another reply, which is the one people seem to have referred to

...R

zhomeslice:
to make the page look pretty (The aggressive part)

I'm sure I'm a bit strange but for me aggressive is almost the opposite of pretty.

I wasn't commenting on your use of Ajax etc to update part of the browser page - that's a good idea. (If you have some spare time maybe you could teach it to the Arduino Forum developers :))

But whatever happens on the browser the Arduino needs to get the PWM value from somewhere and it is much better use of Arduino resources to store it in a variable rather than try and recreate it from the Timer registers.

...R

Robin2:
But whatever happens on the browser the Arduino needs to get the PWM value from somewhere and it is much better use of Arduino resources to store it in a variable rather than try and recreate it from the Timer registers.

...R

I love the insight I am getting.... Your comment you made about the registers made me think How is the arduino compiler actually setting the value for PWM it has to be somewhat easy and simple so I went looking and found what I was looking for. wiring_analog.c is where it is hiding.

so I came up with a function :slight_smile: poof "analouOutputReadPWM" was born :slight_smile:
Here is the working code:

void setup()
{
  Serial.begin(57600);
  pinMode(11, OUTPUT);
  analogWrite(11, 100);
}

void loop() {
  delay(2000);
  setPWM();
  int MyPWMVal = analogOutputReadPWM(11); // this doesn't work but it is what i need to do... HOW can I do this  and is it even possible?
  Serial.print("My PWM Value is:");
  Serial.println(MyPWMVal);
}
void setPWM(){ // represents special code setting the PWM output to some value
  int x = random(0,255);
  Serial.print("Lets set the PWM Value to:");
  Serial.println(x);
  analogWrite(11, x);
}


// THE FOLLOWING FUNCIOTN IS DERIVED FROM:

/*
  wiring_analog.c - analog input and output
  Part of Arduino - http://www.arduino.cc/

  Copyright (c) 2005-2006 David A. Mellis

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA

  Modified 28 September 2010 by Mark Sproul

  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/


// Right now, PWM output only works on the pins with
// hardware support.  These are defined in the appropriate
// pins_*.c file.  For the rest of the pins, are default
// to digital output.
byte analogOutputReadPWM(uint8_t pin){
    byte val;
    switch(digitalPinToTimer(pin)) // returns timer location if it is on a timer see NOT_ON_TIMER 
    {
            // XXX fix needed for atmega8
            #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
            case TIMER0A:
                    val = OCR0;  // get pwm duty
                    break;
            #endif

            #if defined(TCCR0A) && defined(COM0A1)
            case TIMER0A:
                    val = OCR0A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR0A) && defined(COM0B1)
            case TIMER0B:
                    val = OCR0B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR1A) && defined(COM1A1)
            case TIMER1A:
                    val = OCR1A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR1A) && defined(COM1B1)
            case TIMER1B:
                    val = OCR1B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2) && defined(COM21)
            case TIMER2:
                    val = OCR2; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2A) && defined(COM2A1)
            case TIMER2A:
                    val = OCR2A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2A) && defined(COM2B1)
            case TIMER2B:
                    val = OCR2B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3A1)
            case TIMER3A:
                    val = OCR3A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3B1)
            case TIMER3B:
                    val = OCR3B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3C1)
            case TIMER3C:
                    val = OCR3C; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A)
            case TIMER4A:
                    val = OCR4A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A) && defined(COM4B1)
            case TIMER4B:
                    val = OCR4B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A) && defined(COM4C1)
            case TIMER4C:
                    val = OCR4C; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4C) && defined(COM4D1)
            case TIMER4D:				
                    val = OCR4D; // get pwm duty
                    break;
            #endif


            #if defined(TCCR5A) && defined(COM5A1)
            case TIMER5A:
                    val = OCR5A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR5A) && defined(COM5B1)
            case TIMER5B:
                    val = OCR5B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR5A) && defined(COM5C1)
            case TIMER5C:
                    val = OCR5C; // get pwm duty
                    break;
            #endif

            case NOT_ON_TIMER:
            default:
                    val = digitalRead(pin);
    }
    return(val);
}

The first issue that I see with your analogOutputReadPWM() function is it never actually returns val when it completes. I haven't dug into the Arduino AnalogWrite() function to know if any of the other logic is correct, but conceptually reading the register that is controlling the hardware PWM pin is the way to go if you really don't want to remember what value you sent to AnalogWrite() as a global variable and report the contents of that global variable.

I suppose your method would be simpler if one has a 3rd (or even 1st) party library that controls PWM and one doesn't want to bother modifying libraries, and locally maintaining one's fork of the library over updates to the effected library.

P.S. My apologies if I should have used "affected" instead of "effected"... This is one of the grammar rules with which I always have issues.

Robin2:

zhomeslice:
to make the page look pretty (The aggressive part)

I wasn't commenting on your use of Ajax etc to update part of the browser page - that's a good idea. (If you have some spare time maybe you could teach it to the Arduino Forum developers :))
...R

this is off the subject of PWM reading and related to AJAX and arduino:
from my page code I posted earlier, you see this line. the web browser will be using the spot to put what my javascript/jquery code spits out.
client.println("

Place Holder
");

the following javascript would be loaded to the browser using:
client.println(""); // get javascript for my arduino
the website could be any website you can store files on. I own this domain but it could be located anywhere
so for the javascript:

$(function() { // jquery run this once the web page is loaded
    setInterval(ReloadData(), 5000); // retrieves  data from the arduino every 5 seconds
});

function ReloadData(){
     $("#start")..load( "$data #Data" , function() {  // this is all that is needed to load the data into the container using jquery
         // we now have the page from the arduino and only snagged the code between <div id='Data'>......</div> and stores data in the  in the <div id'start'>...</div>
         // the data in each of the div elements is now accessible with simple jquery actions like:
         // var x = $("#A1").text(); // this will store the Text based value for Analog sensor 1 into variable x for processing further with javascript
         // additional processing of the page happens here. The Cool Aggressive stuff I have been mentioning
    }
}

Enjoy

Sembazuru:
The first issue that I see with your analogOutputReadPWM() function is it never actually returns val when it completes. I haven't dug into the Arduino AnalogWrite() function to know if any of the other logic is correct, but conceptually reading the register that is controlling the hardware PWM pin is the way to go if you really don't want to remember what value you sent to AnalogWrite() as a global variable and report the contents of that global variable.

I suppose your method would be simpler if one has a 3rd (or even 1st) party library that controls PWM and one doesn't want to bother modifying libraries, and locally maintaining one's fork of the library over updates to the effected library.

P.S. My apologies if I should have used "affected" instead of "effected"... This is one of the grammar rules with which I always have issues.

Thank you for pointing that out I have corrected in my above code it uniquely enough it worked either way but correctness is more important than details.
I am planning on placing this function in my web page library to allow for simplicity I just need to know what is happening with the arduino. I have i'm mind using a GPS to feed a PID routine to control my H-bridges to drive my tank style rover and so I need to know what is happening, the PID is making changes multiple times a second and I only need to see what is generally happening every 5 seconds or so.

I have been running the sketch on my UNO for a while now with excelent results:

Lets set the PWM Value to:119
My PWM Value is:119
Lets set the PWM Value to:42
My PWM Value is:42
Lets set the PWM Value to:26
My PWM Value is:26

I still can't see why one would use

byte analogOutputReadPWM(uint8_t pin){
    byte val;
    switch(digitalPinToTimer(pin)) // returns timer location if it is on a timer see NOT_ON_TIMER 
    {
            // XXX fix needed for atmega8
            #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
            case TIMER0A:
                    val = OCR0;  // get pwm duty
                    break;
            #endif

            #if defined(TCCR0A) && defined(COM0A1)
            case TIMER0A:
                    val = OCR0A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR0A) && defined(COM0B1)
            case TIMER0B:
                    val = OCR0B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR1A) && defined(COM1A1)
            case TIMER1A:
                    val = OCR1A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR1A) && defined(COM1B1)
            case TIMER1B:
                    val = OCR1B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2) && defined(COM21)
            case TIMER2:
                    val = OCR2; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2A) && defined(COM2A1)
            case TIMER2A:
                    val = OCR2A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR2A) && defined(COM2B1)
            case TIMER2B:
                    val = OCR2B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3A1)
            case TIMER3A:
                    val = OCR3A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3B1)
            case TIMER3B:
                    val = OCR3B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR3A) && defined(COM3C1)
            case TIMER3C:
                    val = OCR3C; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A)
            case TIMER4A:
                    val = OCR4A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A) && defined(COM4B1)
            case TIMER4B:
                    val = OCR4B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4A) && defined(COM4C1)
            case TIMER4C:
                    val = OCR4C; // get pwm duty
                    break;
            #endif

            #if defined(TCCR4C) && defined(COM4D1)
            case TIMER4D:				
                    val = OCR4D; // get pwm duty
                    break;
            #endif


            #if defined(TCCR5A) && defined(COM5A1)
            case TIMER5A:
                    val = OCR5A; // get pwm duty
                    break;
            #endif

            #if defined(TCCR5A) && defined(COM5B1)
            case TIMER5B:
                    val = OCR5B; // get pwm duty
                    break;
            #endif

            #if defined(TCCR5A) && defined(COM5C1)
            case TIMER5C:
                    val = OCR5C; // get pwm duty
                    break;
            #endif

            case NOT_ON_TIMER:
            default:
                    val = digitalRead(pin);
    }
    return(val);
}

in preference to

int myPwmVal = nnn;
  • probably because I'm strange ...

By the way I wasn't expecting any response to my comment about Ajax.

...R

Robin2:
in preference to

int myPwmVal = nnn;
  • probably because I'm strange ...

I can appreciate the simplicity of your code what I want to eventually do is create a library so that all I will need to do is put

#include <MyWebInterface.h>

at the top of any sketch hook up a network cable and have complete access to the arduino's input and outputs in what ever state they may be in (input/output/digital/analog). My original question I was able to solve with the code I provided and it should with all current arduino boards and it could be simplified if it looks like too much for a single board. so yes you are correct that is what would work for any program just get the value at the time you send it to the PWM output. My origional question and post was to get it after some code some where set it. so i didn't have to worry if I have a good value or not it is what is there in one simple sweep.

Thank to all that comments and help.

Apart from very simple libraries with very limited functionality (the servo library being a good example) I believe it would be more useful to spend time writing a tutorial from which Arduino people could learn how to do something rather than spending the same amount of time writing some code to save them the trouble of learning it.

With a tutorial you would be sharing your knowledge with the Arduino community and less experienced people would learn stuff, and probably learn incidental skills and techniques with wider application.

Complex libraries usually (always?) go wrong (or don't exactly meet the user's need) so that the user just wastes time trying to understand and fix the library which would be better spent on their own project.

Of course I might be tempted to soften my views if you intend to include extensive documentation with your library - the sort one would expect to find with a commercial product.

Just my 3 cents worth.

...R

Robin2:
Apart from very simple libraries with very limited functionality (the servo library being a good example) I believe it would be more useful to spend time writing a tutorial from which Arduino people could learn how to do something rather than spending the same amount of time writing some code to save them the trouble of learning it.

With a tutorial you would be sharing your knowledge with the Arduino community and less experienced people would learn stuff, and probably learn incidental skills and techniques with wider application.

Complex libraries usually (always?) go wrong (or don't exactly meet the user's need) so that the user just wastes time trying to understand and fix the library which would be better spent on their own project.

Of course I might be tempted to soften my views if you intend to include extensive documentation with your library - the sort one would expect to find with a commercial product.

Just my 3 cents worth.

...R

I am not sure if I am qualified to try to teach others my concept. My library should be simple. it is the web side code that becomes complex. all the library will do is initialize a simple web page that has a link to a JavaScript file located on a web server. from here the client computer takes over when to request information based on the programming of the JavaScript. The Arduino library needs to be able to gather data for sending over the internet (which is why I needed help in the first place with PWM stuff) and eventually being able to set that data when requested by the client side JavaScript request this should be easy. For now I hope to create a clean simple sketch, a JavaScript file and CSS to tidy up where everything should go. I hope that this will allows me to play with my UNO from my web browser by clicking images of lights to turn them on/off and even entering a value into a form field to easily set PWM levels. all this with direct link feed back to the browser so i can know if anything changes through the automation i will be adding.

I new that there were far better programmers than me. and I quickly got my answer. "difficult" I am sure there is some memory location that is storing that but no quick way to peek at it. I can understand that, so I will have to add more lines of code to store the data probably create a simple function that stores the value before it is handed to the PWM analogWright() funciton.

I don't understand your thinking that you have to add more lines of code to store data before it is handed to the PWM analogWrite() function.

Where are you planning to get your PWM values? If you are reading them from somewhere, you could use something like
analogWrite(pwmPin, Serial.read(); but since you want to send the last value written, you can use:

byte pwmValue = Serial.read();
analogWrite(pwmPin, pwmValue);

Yes, it's one extra line of code, but isn't that a small price to pay so that you don't have to use more lines of code to extract the valuefrom the PWM register?

You want to send in pin states? Use a variable for each pin you are interested in, and only modify any pin's state using the appropriate variable.

My origional question and post was to get it after some code some where set it. so i didn't have to worry if I have a good value or not it is what is there in one simple sweep.

States of pins are set either by code within the Arduino's processor, of by inputs from outside the Arduino's processor. There is not "some code somewhere", that does not consist of one of these two things.