Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. Surface Mount ATMega328p-AU sensor board.

Surface Mount ATMega328p-AU sensor board.

Scheduled Pinned Locked Moved Hardware
poolsmd
5 Posts 3 Posters 4.4k Views 6 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maltimus
    wrote on last edited by maltimus
    #1

    I have been working on a project that will integrate a wide range of sensors into a nice surface mount package for the ATMega328p-au (Arduino chip). I am currently waiting on these boards from OSH Park so they are untested at the moment. I will post an update once it has been tested.

    Board layout:

    • 3-Pin Headers: Each of the 3 pin headers are attached to VCC and Ground with I/O pin in the middle. RELAY = D6, FLOW = D5, A_TEMP = D4, W_TEMP = D3, PRESSURE = A0

    • 4-Pin Headers: Most of the 4 pin headers are for I2C devices and go VCC - SCL - SDA - GND. The exception is TTL which is VCC - RX - TX - GND.

    • Programer header: Top to bottom >> GND - NC - VCC - TX - RX - DTR

    • L1-L3 are WS2812B addressable RGB LED's.

    The board was designed in eagleCAD if anyone was interested in the sch or brd files.

    Link to OSH Park: https://oshpark.com/shared_projects/IVovQwgz

    ![Alt text][1]
    [1]: https://644db4de3505c40a0444-327723bce298e3ff5813fb42baeefbaa.ssl.cf1.rackcdn.com/uploads/project/top_image/IVovQwgz/i.png "SMD Sensor Board"

    1 Reply Last reply
    4
    • R Offline
      R Offline
      RJ_Make
      Hero Member
      wrote on last edited by
      #2

      I like it, looking forward to seeing how your testing goes.

      RJ_Make

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maltimus
        wrote on last edited by maltimus
        #3

        I am glad to report that my first attempt at designing a board went well overall. The project/boards linked in my above post works as is, but I would make a few modifications on future boards. Some of the modifications I will hopefully implement soon are:

        • Addition of holes so the board can be mounted to a project enclosure.
        • Combine the Water/Air Temp sensors onto a single pin to the ATMega328p along with adding a resistor between the data and VCC. Unfortunately, I did not realize that DS18B20's could be chained together to save on pins, or that it needs to have a pull-up resistor.
        • Drop the number of I2C pin connections to one or two. In addition to this I will probably also make a simple breakout board for expanding the number of connections as needed.
        • Include I2C pull up resistors. It has been functioning without any issues without them, but I should have put them on the board.

        The Sketch I have created and have running includes the following sensors so far:

        • Atlas Scientific pH sensor and probe
        • Atlas Scientific ORP sensor and probe
        • (2)Dallas DS18B20 for water and air temp.
        • Relay for pool pump
        • MPX5500DP pressure sensor to monitor water at the filter pressure
        • A 4 line 20 character LCD display currently showing temps/ORP/pH

        The sketch is sending the data to my MIOS as expected. However, when I turn the relay on I have noticed the message is broadcast quite a few times. When debugging is active it seemed that the incoming message would display around a hundred times (I never actually counted the number of times). Is such a large number of attempts to send the message normal? Any feedback or recommendations are welcome.

        Note: I do not have the arduino bootloader running on my boards. I am using the Visual Micro addin for AtmelStudio and an MKII ISP to program the boards.

        #include <SPI.h>
        #include <MySensor.h>
        #include <Wire.h>
        #include <DallasTemperature.h>
        #include <OneWire.h>
        #include <LiquidCrystal_I2C.h>
        
        /*#### MySensor Node definitions  ####*/
        #define NODE_ID 2
        #define PRES_CHILD 0		
        #define WTEMP_CHILD 1
        #define ATEMP_CHILD 2
        #define RELAY_CHILD_ID 3
        #define PH_CHILD_ID 4
        #define ORP_CHILD_ID 5
        
        /*####  Arduino Pin definitions  #####*/
        #define MPX5500DP_PIN	0 // A0 - MPX5500DP pin
        #define WTEMP_PIN		3 // D3 - Dallas one wire temp sensor
        #define ATEMP_PIN		4 // D4 - Dallas one wire temp sensor
        #define PUMP_RELAY		6 // D6 - Relay Pin
        
        /*####    Program definitions     #####*/
        #define PH_I2C 99   			//default I2C ID number for EZO pH Circuit.
        #define ORP_I2C 98  			//default I2C ID number for EZO ORP Circuit.
        #define NUMBER_OF_RELAYS 1 		// Total number of attached relays
        #define RELAY_ON 1  			// GPIO value to write to turn on attached relay
        #define RELAY_OFF 0 			// GPIO value to write to turn off attached relay
        #define MAX_ATTACHED_DS18B20 16	// Define the max number of DS18B20 per pin
        #define LCD_I2C 0x3F 			// I2C address of the LCD screen
        
        /*####   Program variables   #####*/
        unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in mili-seconds)
        int delay_count = 0;
        int periodUpdate = 0;
        LiquidCrystal_I2C lcd(LCD_I2C, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
        
        //temperature variables
        OneWire waterOneWire(WTEMP_PIN);
        DallasTemperature wSensors(&waterOneWire);
        OneWire airOneWire(ATEMP_PIN);
        DallasTemperature aSensors(&airOneWire);
        float atemperature = 0;
        float wtemperature = 0;
        float lastPressure = -1;
        float lastWTemp = -1;
        float lastATemp = -1;
        
        // &&&& pH and ORP &&&&
        byte code=0;                    //used to hold the I2C response code.
        char I2C_data[10];              //we make a 20 byte character array to hold incoming data from the circuit.
        byte in_char=0;                 //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
        byte i=0;                       //counter used for ph_data array.
        float ph_float = 0;             //float var used to hold the float value of the pH.
        float ORP_float = 0;            //float var used to hold the float value of the ORP.
        float last_ph_float = 1;		//float var used to hold the float value of the last pH.
        float last_ORP_float = 1;		//float var used to hold the float value of the last ORP.
        
        
        /*####   My Sensors   #####*/ 
        boolean metric;
        MySensor gw;
        //Message definitions
        MyMessage pHMsg(PH_CHILD_ID, V_VAR1);
        MyMessage orpMsg(ORP_CHILD_ID, V_VAR1);
        MyMessage wTempMsg(WTEMP_CHILD, V_TEMP);
        MyMessage aTempMsg(ATEMP_CHILD, V_TEMP);
        MyMessage pressureMsg(PRES_CHILD, V_PRESSURE);
        
        /*####  Program #####*/
        void setup() {
        	wSensors.begin();
        	aSensors.begin();
        	gw.begin(incomingMessage, NODE_ID, true);
        
        	// Send the sketch version information to the gateway and Controller
        	gw.sendSketchInfo("Sensor Node AlphaMax", "0.1"); // Update Node name for each node -- Update version number for each update.
        
        	// Register sensors to gw (they will be created as child devices)
        	gw.present(PRES_CHILD, S_BARO);
        	gw.present(WTEMP_CHILD, S_TEMP);
        	gw.present(ATEMP_CHILD, S_TEMP);
        	gw.present(PH_CHILD_ID, S_CUSTOM);
        	gw.present(ORP_CHILD_ID, S_CUSTOM);
        	gw.present(RELAY_CHILD_ID, S_LIGHT);
        
        	metric =  gw.getConfig().isMetric;											// getConfig() returns true for metric, false for imperial
        	pinMode(PUMP_RELAY, OUTPUT);												// Then set relay pins in output mode
        	digitalWrite(PUMP_RELAY, gw.loadState(RELAY_CHILD_ID)?RELAY_ON:RELAY_OFF);	// Set relay to last known state (using eeprom storage)
        	lcd.begin(20,4);															// Initialize the lcd for 20 chars 4 lines
        	lcd.clear();																// Clear LCD screen before use
        }
        
        void loop() {
        	gw.process();
        
        	//Get temperature
        	aSensors.requestTemperatures();
        	atemperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?aSensors.getTempCByIndex(0):aSensors.getTempFByIndex(0)) * 100.)) / 100.;
        	wSensors.requestTemperatures();
        	wtemperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?wSensors.getTempCByIndex(0):wSensors.getTempFByIndex(0)) * 100.)) / 100.;
        	//Get pressure
        	float pressure = analogRead(MPX5500DP_PIN); //MPX5500DP Pressure sensor	
        	//Get ph and ORP
        	atlas(PH_I2C);
        	atlas(ORP_I2C);
        	//Update LCD Screen
        	printscreen();
        
        	//Update VERA when needed.
        	if (ph_float != last_ph_float)
        	{
        		gw.send(pHMsg.set(ph_float,2));
        		last_ph_float = ph_float;
        	}
        	if (ORP_float != last_ORP_float)
        	{
        		gw.send(orpMsg.set(ORP_float,1));
        		last_ORP_float = ORP_float;
        	}
        	//Periodic updates were used when LCD display was on another node
        	//since they do not appear to be hurting anything I left them in.
        	if (wtemperature != lastWTemp | periodUpdate == 250000) {	
        		gw.send(wTempMsg.setDestination(0).set(wtemperature,1));
        		lastWTemp = wtemperature;
        	}
        	if (atemperature != lastATemp | periodUpdate == 500000) {
        		gw.send(aTempMsg.setDestination(0).set(atemperature,1));
        		lastATemp = atemperature;
        	}
        	if (pressure != lastPressure | periodUpdate == 750000) {
        		gw.send(pressureMsg.set(pressure, 0));
        		lastPressure = pressure;
        	}
        	if(periodUpdate >= 750000)
        	{
        		periodUpdate = 0;
        	}
        	periodUpdate++;
        }
        
        //This function is used to handle data to and from the ORP and pH sensors
        void atlas(int address){	
        	
        	Wire.beginTransmission(address); //call the circuit by its ID number.
        	Wire.write('R');				 //transmit the command that was sent through the serial port.
        	Wire.endTransmission();          //end the I2C data transmission.
        	
        	for(int k=0;k<=140;k++)			// Need to delay 1.4 seconds between sending read command
        	{								// and requesting data. This for loop keeps delays between
        		gw.process();				// processing incoming messages short.
        		delay(10);
        	}
        	
        	Wire.requestFrom(address,20,1); //call the circuit and request 20 bytes (this may be more then we need).
        	code=Wire.read();               //the first byte is the response code, we read this separately.
        	switch (code){                  //switch case based on what the response code is.
        		case 1:                     //decimal 1.
        		Serial.println("Success");  //means the command was successful.
        		break;                      //exits the switch case.
        		
        		case 2:                     //decimal 2.
        		Serial.println("Failed");   //means the command has failed.
        		break;                      //exits the switch case.
        		
        		case 254:                   //decimal 254.
        		Serial.println("Pending");  //means the command has not yet been finished calculating.
        		break;                      //exits the switch case.
        		
        		case 255:                   //decimal 255.
        		Serial.println("No Data");  //means there is no further data to send.
        		break;                      //exits the switch case.
        	}
        	while(Wire.available()){        //are there bytes to receive.
        		in_char = Wire.read();      //receive a byte.
        		I2C_data[i]= in_char;       //load this byte into our array.
        		i+=1;                       //incur the counter for the array element.
        		if(in_char==0){             //if we see that we have been sent a null command.
        			i=0;                    //reset the counter i to 0.
        			Wire.endTransmission(); //end the I2C data transmission.
        			break;                  //exit the while loop.
        		}
        	}
        	Serial.println(I2C_data);       //print the data.
        	
        	if(address == PH_I2C)
        	{
        		ph_float = atof(I2C_data);
        	}
        	else if(address == ORP_I2C)
        	{
        		ORP_float = atof(I2C_data);		
        	}
        	else
        	Serial.print("No address match!!!!");
        }
        
        void incomingMessage(const MyMessage &message) 
        {
        	// We only expect one type of message from controller. But we better check anyway.
        	if (message.type==V_LIGHT) 
        	{
        		// Change relay state
        		digitalWrite(PUMP_RELAY, message.getBool()?RELAY_ON:RELAY_OFF);
        		// Store state in eeprom
        		gw.saveState(RELAY_CHILD_ID, message.getBool());
        		// Write some debug info
        		Serial.print("Incoming change for sensor:");
        		Serial.print(message.sensor);
        		Serial.print(", New status: ");
        		Serial.println(message.getBool());
        	}
        }
        
        void printscreen()
        {
        	lcd.clear();
        	
        	lcd.setCursor(0,0);
        	lcd.print("Water Temp ");
        	lcd.setCursor(11,0);
        	lcd.print(wtemperature);
        	
        	lcd.setCursor(0,1);
        	lcd.print("Air Temp");
        	lcd.setCursor(11,1);
        	lcd.print(atemperature);
        	
        	lcd.setCursor(0,2);
        	lcd.print("pH");
        	lcd.setCursor(11,2);
        	lcd.print(ph_float);
        	
        	lcd.setCursor(0,3);
        	lcd.print("ORP");
        	lcd.setCursor(11,3);
        	lcd.print(ORP_float);
        }
        
        1 Reply Last reply
        0
        • R Offline
          R Offline
          rvendrame
          Hero Member
          wrote on last edited by
          #4

          The relay switch causes "noise" into the power lines, which drives the radio (mostly) and arduino (sometimes) crazy.

          How are you powering your arduino / radio?

          Home Assistant / Vera Plus UI7
          ESP8266 GW + mySensors 2.3.2
          Alexa / Google Home

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maltimus
            wrote on last edited by
            #5

            I have been using an old(cheap) wall-to-USB power supply. I'll give it a try with a beefier supply and let you know the results I get.

            1 Reply Last reply
            0

            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

            With your input, this post could be even better 💗

            Register Login
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            13

            Online

            12.0k

            Users

            11.2k

            Topics

            113.4k

            Posts


            Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • MySensors
            • OpenHardware.io
            • Categories
            • Recent
            • Tags
            • Popular