Show Posts
Pages: [1] 2
1  Using Arduino / Microcontrollers / Re: Custom board review please on: April 06, 2014, 07:51:21 pm
I just tried bypassing the diode with and my new prox's do not have the same issue.

Old prox's http://www.ebay.com/itm/3x-LJ12A3-4-Z-BX-Inductive-Sensor-Prox-Switch-NPN-6V-36V-CNC-3D-Printer-Arduino-/161246109278?pt=LH_DefaultDomain_0&hash=item258b045e5e

New prox's http://www.newark.com/autonics/prcm12-2dn/inductive-proximity-sensor/dp/10R6710

2  Using Arduino / Microcontrollers / Re: Custom board review please on: April 06, 2014, 10:39:02 am
The 6 3 pin connectors at the top are for the 24vdc NPN under and over travel inductive proximity sensors. The 24vdc power for the prox's connects using the 2 pin connector on the right. I had a weird issue with the leds on all the prox's being on constantly. When the prox was made active then the led would get brighter. This was with the gnd of the 5vdc supply and the gnd of the 24vdc power supply connected together directly. I found adding in the diode prevented that from happening. I replaced my original prox's with some better ones and I haven't tested them without thus diode in place to see if the react differently.
3  Using Arduino / Microcontrollers / Re: Custom board review please on: April 03, 2014, 09:03:54 pm
It was layed out in eagle.

I kind of just went off what I had in my head as well as looked at other schematics. I know it's kind of like having the trailer before the tractor. My boards are not usually overly complicated but I know I need to start creating a schematic first as I always seem to have 1 or 2 small mistakes in my boards. Maybe this weekend I get one made up.

All components are mounted on the same side of the board. The crystal, capacitors, resistor and diode all fit within the dip socket under the chip. I already had a board made up with this arrangement and it worked well and looks very clean.

I did go through and change the resistors so they lay flat.

Also is it ok to have a ground plane on both sides of the board?
4  Using Arduino / Microcontrollers / Re: Custom board review please on: April 02, 2014, 09:06:36 pm
I do not currently. I should start doing those first, probably lead to less mistakes.
5  Using Arduino / Microcontrollers / Re: Custom board review please on: April 02, 2014, 08:55:38 pm
I guess I have a few questions.

The under/over travel limits are NPN. The common comes back on the middle terminal, goes through a 22ohm resistor to the base of the 2n3906 transistor with a 220 ohm resistor to 5v. 5v to collector. The emitter goes to the arduino digital pin with a 10k resistor to ground as well as another 220 ohm resistor inline with a led.

I went off this tutorial to get the resistor values. http://www.rason.org/Projects/transwit/transwit.htm Not sure how I came to 22ohm the first time I did the calculations but now I think is not correct. . Now I'm coming out to around 2k ohm.

Does the reset line look correct? I had a similar board made up but the transistor inputs from the prox's are not on the board or the relay. On my first design I had the receive and transmit lines flipped. I broke the traces and used pieces of wire to fix my screw up and was testing the board out today and it reset on its own a few times.

6  Using Arduino / Microcontrollers / Custom board review please on: April 02, 2014, 07:31:57 pm
Designed an atmega1284p board for controlling my cnc. Just like to get some opinions before I send out to have it made up.





R1 - R6 = 22 ohm
R7 - R18 = 220 ohm
R19 - R26 = 10k ohm
Q1 - Q6 = 2N3906
Q7 = 2N2222A
C5 & C6 = 22pF
C1, C3, C4 & C7 = 0.1uF
C2 = 100uF
D7 & D8 = 1N4001
D9 = 1N4148
Y1 = 16MHz

Board has a ground plane front and back.
7  Using Arduino / Programming Questions / Re: timers and direct port manipulation on: February 13, 2014, 11:15:35 am
I take it that if I need to set an input pin HIGH (enable internal pullup) I need to toggle the appropriate bit within the PORTx register???

my overtravel prox's connect to GND when active, they are NPN.
8  Using Arduino / Programming Questions / Re: timers and direct port manipulation on: February 10, 2014, 01:36:34 pm
Quote
Is that not the proper way to do a while statement?
The syntax is valid. But, the compiler sees that the while loop accomplishes nothing. So, it removes it. Wasting time is not something that the compiler supports. delayMicroseconds() could be used.

Why are you trying to step the motor using just a timer? How do you plan to control direction?
Thanks.

I'm actually working on the code for a 3 axis cnc mill. Through the serial monitor I enter in the axis I want to move followed by the position I want it to go to. I couldn't get any of the axis to move using that code so I dumbed it down severly so I could find what the issue is. In my cnc code the timer is setup in ctc mode instead of overflow. There is an output for direction that is toggled based on the commanded position vs the actual position.

My plan is to use grbl but not until I understand what is going on behind the scenes.
9  Using Arduino / Programming Questions / Re: timers and direct port manipulation on: February 10, 2014, 12:36:06 pm
You can toggle an IO pin with just this:

PINB = 0b00000100;  // write a 1 to input register to toggle the bit

"Three I/O memory address locations are allocated for each port, one each for the Data Register
– PORTx, Data Direction Register
– DDRx, and the Port Input Pins
– PINx.
The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write.
However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register."

Is it is recommended to OR the port pin register to avoid changing the state of pins you don't wanted changed.
10  Using Arduino / Programming Questions / Re: timers and direct port manipulation on: February 10, 2014, 12:20:23 pm
Thanks Guys, Is that not the proper way to do a while statement? I need a slight delay before toggling the pin back to its original state or the stepper driver does not detect a pulse.
11  Using Arduino / Programming Questions / timers and direct port manipulation on: February 10, 2014, 10:16:05 am
I'm trying to setup timer 1 to toggle a digital pin for the pulse signal to a stepper motor driver. I'm using an Atmega1284P.

I can't seem to get the pin to toggle. It goes high and seems to stay high. Digital pin 3, Port B pin 3

Code:
// avr-libc library includes
#include <avr/io.h>
#include <avr/interrupt.h>
    
void setup() {
  DDRB |= 0x08;
  PORTB |= 0x08;
  cli();          // disable global interrupts  
  TCCR1A = 0;     // set entire TCCR3A register to 0
  TCCR1B = 0;     // same for TCCR3B
  
  // enable Timer1 overflow interrupt:
  TIMSK1 |= (1 << TOIE1);
  // Set CS10 bit to start timer with no prescaler, timer will overflow every 4.1ms
  TCCR1B |= (1 << CS10);
  sei();
}
void loop() {

}

ISR (TIMER1_OVF_vect) {
  int z = 0;
  
  PORTB &= ~0x08;
  while(z++ != 10);
  PORTB |= 0x08;
}

I verified the wiring and hardware side is setup correctly by running this sketch and it works fine.
Code:
int dirpin = 24;
int steppin = 3;

void setup()
{
pinMode(dirpin, OUTPUT);
pinMode(steppin, OUTPUT);
}
void loop()
{

  int i;

  digitalWrite(dirpin, LOW);     // Set the direction.
  delay(3000);


  for (i = 0; i<8000; i++)       // Iterate for 4000 microsteps.
  {
    digitalWrite(steppin, LOW);  // This LOW to HIGH change is what creates the
    digitalWrite(steppin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
    delayMicroseconds(700);      // This delay time is close to top speed for this
  }                              // particular motor. Any faster the motor stalls.

  digitalWrite(dirpin, HIGH);    // Change direction.
  delay(3000);


  for (i = 0; i<8000; i++)       // Iterate for 4000 microsteps
  {
    digitalWrite(steppin, LOW);  // This LOW to HIGH change is what creates the
    digitalWrite(steppin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
    delayMicroseconds(700);      // This delay time is close to top speed for this
  }                              // particular motor. Any faster the motor stalls.

}

Thanks,
12  Using Arduino / Programming Questions / Re: Code Review on: January 28, 2014, 01:44:48 pm
hints received (or atleast I hope so)

Code:
/*Command all 3 axis, 1 at a time, to move until it hits its undertravel limit switch, then change direction and
move until it hits its overtravel limit switch, and then record the amount of pulses it took to go limit to limit,
divide that value in half and go to that position then stop.*/
  
// avr-libc library includes
#include <avr/io.h>
#include <avr/interrupt.h>

#define RUN_ENABLE 0x80 //Axis "ENABLE" Control Bit, PIN 8

const byte X_DIR = 0x04; //X axis "DIRECTION" Control Bit, PIN 2
const byte X_STEP = 0x08; //X Axis "STEP" Control Bit, PIN 3
const byte Y_DIR = 0x10; //X axis "DIRECTION" Control Bit, PIN 2
const byte Y_STEP = 0x20; //X Axis "STEP" Control Bit, PIN 3
const byte Z_DIR = 0x40; //X axis "DIRECTION" Control Bit, PIN 2
const byte Z_STEP = 0x80; //X Axis "STEP" Control Bit, PIN 3
const byte X_UNDERTRAVELPROX = PINC5;  //X Axis over travel prox input, PIN A5
const byte X_OVERTRAVELPROX = PINC4;  //X Axis under travel prox input, PIN A4
const byte Y_UNDERTRAVELPROX = PINC3;  //Y Axis over travel prox input, PIN A3
const byte Y_OVERTRAVELPROX = PINC2;  //Y Axis under travel prox input, PIN A2
const byte Z_UNDERTRAVELPROX = PINC1;  //Z Axis over travel prox input, PIN A1
const byte Z_OVERTRAVELPROX = PINC0;  //Z Axis under travel prox input, PIN A0

//pointers
const byte *STEP;
const byte *DIR;
const byte *UNDERTRAVELPROX;
const byte *OVERTRAVELPROX;
int *ACTUALPOS;
int *COMMANDPOS;
int *MAXSTEPS;

char activeaxis = 0;
int motionenable = 0;
int sequence = 0;
/*
seq 0 = idle
seq 1 = move active axis until under travel prox is made
seq 2 = move active axis until over travel prox is made then record
        number of pulses from under travel to over travel prox
seq 3 = move active axis to center of travel
*/

int index = 0;

int xaxismaxsteps;
int xaxiscommandpos;
int xaxisactualpos;
int yaxismaxsteps;
int yaxiscommandpos;
int yaxisactualpos;
int zaxismaxsteps;
int zaxiscommandpos;
int zaxisactualpos;

int feedrate = 9999;    //5ms pulse interval, 0.0492in/sec feedrate
    
void setup() {
  DDRD |= 0xFC;  // sets digital pins 2,3,4,5,6,7 as output, step and direction pins
  DDRB |= 0x01;  // sets digital pin 8 as output, stepper drivers enable pin
  PORTD |= 0xD8; // sets digital pins 2,3,4,5,6,7 HIGH (internal pull-up resistor)

  cli();          // disable global interrupts  
  // initialize Timer2
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler:
  TCCR1B |= (1 << CS11);
}
  
void loop() {
  // set compare match register equal to feedrate
  OCR1A = feedrate;
  // enable global interrupts:
  sei();
  
  if ((sequence == 0) && (index < 3)) {
    if (activeaxis == 0) { //first run
      activeaxis = 'X';
      //assign pointers
      DIR = &X_DIR;  //sets DIR to the memory address location of X_DIR
      STEP = &X_STEP;  //sets STEP to the memory address location of X_STEP
      UNDERTRAVELPROX = &X_UNDERTRAVELPROX;
      OVERTRAVELPROX = &X_OVERTRAVELPROX;
      ACTUALPOS = &xaxisactualpos;
      COMMANDPOS = &xaxiscommandpos;
      MAXSTEPS = &xaxismaxsteps;
    }
    else if (activeaxis == 'X') {
      activeaxis = 'Y';
      //assign pointers
      DIR = &Y_DIR;
      STEP = &Y_STEP;
      UNDERTRAVELPROX = &Y_UNDERTRAVELPROX;
      OVERTRAVELPROX = &Y_OVERTRAVELPROX;
      ACTUALPOS = &yaxisactualpos;
      COMMANDPOS = &yaxiscommandpos;
      MAXSTEPS = &yaxismaxsteps;
    }
    else if (activeaxis == 'Y') {
      activeaxis = 'Z';
      //assign pointers
      DIR = &Z_DIR;
      STEP = &Z_STEP;
      UNDERTRAVELPROX = &Z_UNDERTRAVELPROX;
      OVERTRAVELPROX = &Z_OVERTRAVELPROX;
      ACTUALPOS = &zaxisactualpos;
      COMMANDPOS = &zaxiscommandpos;
      MAXSTEPS = &zaxismaxsteps;
    }
    //set direction of active axis to reverse
    PORTD &= ~*DIR;
    //zero active axis position
    *ACTUALPOS = 0;    // zero actual steps
    //command active axis to maximum negative position
    *COMMANDPOS = -32768;
    sequence = 1;  //advance to the next sequence
    motionenable = 1;
    // enable timer 1 compare interrupt used for pulsing stepper driver output:
    TIMSK1 |= (1 << OCIE1A);
  }

  if ((sequence == 1) && (*UNDERTRAVELPROX != 1)) {  //under travel prox reached
    motionenable = 0; // disable motion
    *ACTUALPOS = 0;    // zero actual steps
    *COMMANDPOS = 32768;    //command axis to maximum positive position
    // change direction of X axis
    PORTD |= *DIR; // set pin HIGH    
    sequence = 2;  //advance to the next sequence
    motionenable = 1; // enable motion
  }
  if ((sequence == 2) && (*OVERTRAVELPROX != 1)) {
    motionenable = 0; // disable motion
    *MAXSTEPS = *ACTUALPOS;
    *COMMANDPOS = (*MAXSTEPS / 2);
    // change direction of X axis
    PORTD &= ~*DIR; // set pin LOW    
    sequence = 3;  //advance to the next sequence
    motionenable = 1; // enable motion
  }
  if ((sequence == 3) && (*ACTUALPOS == *COMMANDPOS)) {
    motionenable = 0; // disable motion
    sequence = 0;  //loop back to sequence 0
    index ++;
  }
}

ISR (TIMER1_COMPA_vect) {
  int t =0;
  
  if (motionenable == 1) {
    if((PORTD & *DIR) != ~*DIR) //If going forward, increment active axis position counter
      *ACTUALPOS++;
    else //If going reverse, decrement axis position counter
      *ACTUALPOS--;
    if (*ACTUALPOS != *COMMANDPOS) { //If we are not at our commanded position    
      PORTD &= ~*STEP; //Toggle "Step" output with each entry
      while(t++ != 10);
        PORTD |= *STEP;
    }
  }
}
13  Using Arduino / Programming Questions / Re: Code Review on: January 28, 2014, 01:32:04 pm
No, I tried setting them to const int but then I get compling error: invalid conversion from 'const int*' to 'int*'
14  Using Arduino / Programming Questions / Code Review on: January 28, 2014, 12:42:04 pm
I built myself a 10"x8"x3" cnc for milling pcb boards and other things and possibly in the future 3d printing. Plan is to use GRBL on an atmega328p board that I designed. Anyways even though I plan to use GRBL I want to learn and understand what is happening behind the scenes and in the end learn c and programming avrs. And maybe one day write my own code to control the cnc.

I wrote the following code just as a mechanical and electrical test of all 3 axis.

This is the first time I've worked with timers (I did do a simple blink sketch using timer CTC and had the LED on pin 13 blinking every 1 second), direct port manipulation and pointers.

Code:
/*Command all 3 axis, 1 at a time, to move until it hits its undertravel limit switch, then change direction and
move until it hits its overtravel limit switch, and then record the amount of pulses it took to go limit to limit,
divide that value in half and go to that position then stop.*/
  
// avr-libc library includes
#include <avr/io.h>
#include <avr/interrupt.h>

#define RUN_ENABLE 0x80 //Axis "ENABLE" Control Bit, PIN 8

int X_DIR = 0x04; //X axis "DIRECTION" Control Bit, PIN 2
int X_STEP = 0x08; //X Axis "STEP" Control Bit, PIN 3
int Y_DIR = 0x10; //X axis "DIRECTION" Control Bit, PIN 2
int Y_STEP = 0x20; //X Axis "STEP" Control Bit, PIN 3
int Z_DIR = 0x40; //X axis "DIRECTION" Control Bit, PIN 2
int Z_STEP = 0x80; //X Axis "STEP" Control Bit, PIN 3
int X_UNDERTRAVELPROX = PINC5;  //X Axis over travel prox input, PIN A5
int X_OVERTRAVELPROX = PINC4;  //X Axis under travel prox input, PIN A4
int Y_UNDERTRAVELPROX = PINC3;  //Y Axis over travel prox input, PIN A3
int Y_OVERTRAVELPROX = PINC2;  //Y Axis under travel prox input, PIN A2
int Z_UNDERTRAVELPROX = PINC1;  //Z Axis over travel prox input, PIN A1
int Z_OVERTRAVELPROX = PINC0;  //Z Axis under travel prox input, PIN A0

//pointers
int *STEP;
int *DIR;
int *UNDERTRAVELPROX;
int *OVERTRAVELPROX;
int *ACTUALPOS;
int *COMMANDPOS;
int *MAXSTEPS;

char activeaxis = 0;
int motionenable = 0;
int sequence = 0;
/*
seq 0 = idle
seq 1 = move active axis until under travel prox is made
seq 2 = move active axis until over travel prox is made then record
        number of pulses from under travel to over travel prox
seq 3 = move active axis to center of travel
*/

int index = 0;

int xaxismaxsteps;
int xaxiscommandpos;
int xaxisactualpos;
int yaxismaxsteps;
int yaxiscommandpos;
int yaxisactualpos;
int zaxismaxsteps;
int zaxiscommandpos;
int zaxisactualpos;

int feedrate = 9999;    //5ms pulse interval, 0.0492in/sec feedrate
    
void setup() {
  DDRD |= 0xFC;  // sets digital pins 2,3,4,5,6,7 as output, step and direction pins
  DDRB |= 0x01;  // sets digital pin 8 as output, stepper drivers enable pin
  PORTD |= 0xD8; // sets digital pins 2,3,4,5,6,7 HIGH (internal pull-up resistor)

  cli();          // disable global interrupts  
  // initialize Timer2
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler:
  TCCR1B |= (1 << CS11);
}
  
void loop() {
  // set compare match register equal to feedrate
  OCR1A = feedrate;
  // enable global interrupts:
  sei();
  
  if ((sequence == 0) && (index < 3)) {
    if (activeaxis == 0) { //first run
      activeaxis = 'X';
      //assign pointers
      DIR = &X_DIR;  //sets DIR to the memory address location of X_DIR
      STEP = &X_STEP;  //sets STEP to the memory address location of X_STEP
      UNDERTRAVELPROX = &X_UNDERTRAVELPROX;
      OVERTRAVELPROX = &X_OVERTRAVELPROX;
      ACTUALPOS = &xaxisactualpos;
      COMMANDPOS = &xaxiscommandpos;
      MAXSTEPS = &xaxismaxsteps;
    }
    else if (activeaxis == 'X') {
      activeaxis = 'Y';
      //assign pointers
      DIR = &Y_DIR;
      STEP = &Y_STEP;
      UNDERTRAVELPROX = &Y_UNDERTRAVELPROX;
      OVERTRAVELPROX = &Y_OVERTRAVELPROX;
      ACTUALPOS = &yaxisactualpos;
      COMMANDPOS = &yaxiscommandpos;
      MAXSTEPS = &yaxismaxsteps;
    }
    else if (activeaxis == 'Y') {
      activeaxis = 'Z';
      //assign pointers
      DIR = &Z_DIR;
      STEP = &Z_STEP;
      UNDERTRAVELPROX = &Z_UNDERTRAVELPROX;
      OVERTRAVELPROX = &Z_OVERTRAVELPROX;
      ACTUALPOS = &zaxisactualpos;
      COMMANDPOS = &zaxiscommandpos;
      MAXSTEPS = &zaxismaxsteps;
    }
    else {
      activeaxis = 0;
      //assign pointers
      DIR = NULL;
      STEP = NULL;
      UNDERTRAVELPROX = NULL;
      OVERTRAVELPROX = NULL;
      ACTUALPOS = NULL;
      COMMANDPOS = NULL;
      MAXSTEPS = NULL;
    }
    //set direction of active axis to reverse
    PORTD &= ~*DIR;
    //zero active axis position
    *ACTUALPOS = 0;    // zero actual steps
    //command active axis to maximum negative position
    *COMMANDPOS = -32768;
    sequence = 1;  //advance to the next sequence
    motionenable = 1;
    // enable timer 1 compare interrupt used for pulsing stepper driver output:
    TIMSK1 |= (1 << OCIE1A);
  }

  if ((sequence == 1) && (*UNDERTRAVELPROX == 1)) {  //under travel prox reached
    motionenable = 0; // disable motion
    *ACTUALPOS = 0;    // zero actual steps
    *COMMANDPOS = 32768;    //command axis to maximum positive position
    // change direction of X axis
    PORTD |= *DIR; // set pin HIGH    
    sequence = 2;  //advance to the next sequence
    motionenable = 1; // enable motion
  }
  if ((sequence == 2) && (*OVERTRAVELPROX == 1)) {
    motionenable = 0; // disable motion
    *MAXSTEPS = *ACTUALPOS;
    *COMMANDPOS = (*MAXSTEPS / 2);
    // change direction of X axis
    PORTD &= ~*DIR; // set pin LOW    
    sequence = 3;  //advance to the next sequence
    motionenable = 1; // enable motion
  }
  if ((sequence == 3) && (*ACTUALPOS == *COMMANDPOS)) {
    motionenable = 0; // disable motion
    sequence = 0;  //loop back to sequence 0
    index ++;
  }
}

ISR (TIMER1_COMPA_vect) {
  int t =0;
  
  if (motionenable == 1) {
    if((PORTD & *DIR) != ~*DIR) //If going forward, increment active axis position counter
      *ACTUALPOS++;
    else //If going reverse, decrement axis position counter
      *ACTUALPOS--;
    if (*ACTUALPOS != *COMMANDPOS) { //If we are not at our commanded position    
      PORTD |= *STEP; //Toggle "Step" output with each entry
      while(t++ != 10);
        PORTD &= ~*STEP;
    }
  }
}

My next code challenge will be linear interpolation, making 2 axis start and stop at the same time no matter the difference in distance that each axis has to travel.
15  Community / Exhibition / Gallery / Re: Arduino Webserver with Temperature Monitor / Control on: November 24, 2012, 04:21:58 pm
Finally realized how the ethercard code works and was able to edit your original code. Added 3 more text input boxes to the web page. My code has day and night temperature set points as well as day and night start times. I added a real time clock so it will automatically change the target temp based on the times i set on the web page. Thanks again for the source code, I didn't know what I was getting into when I got the Enc28J60 module.

Code:
#include <EtherCard.h>
#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

char DayTempTextbox[4];               // Data in text box
char NightTempTextbox[4];             // Data in text box
char DayTimeTextbox[4];               // Data in text box
char NightTimeTextbox[4];             // Data in text box

// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA };
static byte myip[] = { 192,168,1,102 }; //used for static IP

byte Ethernet::buffer[1000];
BufferFiller bfill;

byte TargetTemp = 65;                     
byte DayTempSP = 70;
byte NightTempSP = 68;
byte DayStartTime = 7;
byte NightStartTime = 20;
byte value;

byte TempSensor = A3;
byte HeatONRelay1 = 3;
byte HeatONRelay2 = 4;

const int numReadings = 15;
byte TempReading[numReadings];
byte TempIndex = 0;
int TempTotal = 0;

byte RoomTemperature = 0;
byte TempDBMax = 71;
byte TempDBMin = 69;
byte TempDeadBandSP = 1;

byte Hour = 12;
byte Minute = 24;
byte Second = 36;
byte Month = 11;
byte Day = 23;
int Year = 2012;

//====================================================================================================
void setup () {
//====================================================================================================
  if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0);
  ether.staticSetup(myip);
  Wire.begin();
  RTC.begin();
  pinMode(HeatONRelay1, OUTPUT);          // sets the digital pin as input
  pinMode(HeatONRelay2, OUTPUT);          // sets the digital pin as input
 
  analogReference(INTERNAL); 
 
  DayTempSP = EEPROM.read(0);
  NightTempSP = EEPROM.read(1);
  DayStartTime = EEPROM.read(2);
  NightStartTime = EEPROM.read(3);
   
}

//====================================================================================================

const char http_OK[] PROGMEM =
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
    "HTTP/1.0 302 Found\r\n"
    "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
    "HTTP/1.0 401 Unauthorized\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<h1>401 Unauthorized</h1>";

//====================================================================================================
static word homePage() {
//====================================================================================================

//$D = word data type
//$L = long data type
//$S = c string
//$F = progmem string
//$E = byte from the eeprom.

  char* Heatstat;
  if ( digitalRead(HeatONRelay1) == HIGH ) {
    Heatstat = "On" ; }
  else {
    Heatstat = "Off"; }
   
  bfill.emit_p(PSTR(
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Pragma: no-cache\r\n"
  "\r\n"
  "<!DOCTYPE html>"
  "<html><head>"
  "<meta http-equiv='refresh' content='10'/>"
  "<title>ArduStat</title>"
  "<body bgcolor=""#99CCFF"">"
  "<center>"
  "<hr />"
  "Temperature: <b>"
  "<br />"
  "<font size=""5"">"
  "$D &deg;F</font></b>"   
  "<br />"
  "Current Target Temperature: <b>"
  "$D &deg;F</b>"
  "<br />"
  "Heat is <b>$S</b> "
  "<hr />"
  "Current Temperature Setpoint: <b><font size=""4"">$D &deg;F</font></b>"
  "<form><input type=text name=daytemp size=4> <input type=submit value=Ok> </form>"
  "Current Start Time: <b><font size=""4"">$D</font></b>"     
  "<form><input type=text name=daytime size=4> <input type=submit value=Ok> </form>"
  "Current Temperature Setpoint: <b><font size=""4"">$D &deg;F</font></b>"
  "<form><input type=text name=nighttemp size=4> <input type=submit value=Ok> </form>" 
  "Current Start Time: <b><font size=""4"">$D</font></b>"
  "<form><input type=text name=nighttime size=4> <input type=submit value=Ok> </form>"
  "<hr />"
  "Date: $D/$D/$D Time: $D:$D:$D "     
  "</center></body></html>"),
  RoomTemperature, TargetTemp, Heatstat, DayTempSP, DayStartTime, NightTempSP, NightStartTime, Month, Day, Year, Hour, Minute, Second );
  return bfill.position();
         
}
//====================================================================================================
void loop () {
//====================================================================================================

  DateTime now = RTC.now();
  Month = now.month();
  Day = now.day();
  Year = now.year();
  Hour = now.hour();
  Minute = now.minute();
  Second = now.second();
 
  TempTotal = TempTotal - TempReading[TempIndex];
  TempReading[TempIndex] = ((analogRead(TempSensor)/9.31)-3);
  TempTotal = TempTotal + TempReading[TempIndex];
  TempIndex = TempIndex + 1;
  if (TempIndex >= numReadings) {
    TempIndex = 0; }
  RoomTemperature = TempTotal / numReadings;
 
  if ((Hour >= DayStartTime) & (Hour < NightStartTime)) {
    TargetTemp = DayTempSP; }
     
  if ((Hour >= NightStartTime) | (Hour < DayStartTime)) {
    TargetTemp = NightTempSP; }
 
  TempDBMin = (TargetTemp - TempDeadBandSP);
  TempDBMax = (TargetTemp + TempDeadBandSP); 
 
  if (RoomTemperature < TempDBMin) {
    digitalWrite(HeatONRelay1, HIGH);
    digitalWrite(HeatONRelay2, HIGH); }
  if (RoomTemperature > TempDBMax) {
    digitalWrite(HeatONRelay1, LOW);
    digitalWrite(HeatONRelay2, LOW); }
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
 
  if (pos) {
    delay(1);   // necessary for my system //TODO
    bfill = ether.tcpOffset();
    char *data = (char *) Ethernet::buffer + pos;
    if (strncmp("GET /", data, 5) != 0) {
      bfill.emit_p(http_Unauthorized); }
    else {
      data += 5;
      if (data[0] == ' ') {
        homePage(); }
      else if (strncmp( "?daytemp=" , data , 8 ) == 0) {
        if (ether.findKeyVal(data + 1, DayTempTextbox , sizeof DayTempTextbox , "daytemp") > 0) {
          value = atoi(DayTempTextbox);   // command to convert a string to number
          if ((value >= 55) & (value <= 80)) {
            DayTempSP = value;
            EEPROM.write(0, value); }
        }
        bfill.emit_p(http_Found);
      }
      else if (strncmp( "?daytime=" , data , 8 ) == 0) {
        if (ether.findKeyVal(data + 1, DayTimeTextbox , sizeof DayTimeTextbox , "daytime") > 0) {
          value = atoi(DayTimeTextbox);   // command to convert a string to number
          if ((value > 0) & (value <= 24)) {
            DayStartTime = value;
            EEPROM.write(2, value); }
        }
        bfill.emit_p(http_Found);
      }
      else if (strncmp( "?nighttemp=" , data , 10 ) == 0) {
        if (ether.findKeyVal(data + 1, NightTempTextbox , sizeof NightTempTextbox , "nighttemp") > 0) {
          value = atoi(NightTempTextbox);   // command to convert a string to number
          if ((value >= 55) & (value <= 80)) {
             NightTempSP = value;
            EEPROM.write(1, value); }
        }
        bfill.emit_p(http_Found);
      } 
      else if (strncmp( "?nighttime=" , data , 10 ) == 0) {
        if (ether.findKeyVal(data + 1, NightTimeTextbox , sizeof NightTimeTextbox , "nighttime") > 0) {
          value = atoi(NightTimeTextbox);   // command to convert a string to number
          if ((value > 0) & (value <= 24)) {
            NightStartTime = value;
            EEPROM.write(3, value); }
        }
        bfill.emit_p(http_Found);
      }
      ether.httpServerReply(bfill.position());
    }
  }
}

webpage:
Pages: [1] 2