Team:TU-Munich/Results/How To

From 2013.igem.org

(Difference between revisions)
(Code)
m (Code)
Line 292: Line 292:
Now you are ready to start programming. We'd like to share our code. Feel free to use, edit and play around with it!
Now you are ready to start programming. We'd like to share our code. Feel free to use, edit and play around with it!
-
<code>
+
<nowiki>
#include "SPI.h" // SPI library (stock)
#include "SPI.h" // SPI library (stock)
#include "Wire.h" // TwoWire library (stock) sda-scl
#include "Wire.h" // TwoWire library (stock) sda-scl
Line 597: Line 597:
delay(1);
delay(1);
}
}
-
</code>
+
 
 +
</nowiki>
<div class="visualClear"></div>
<div class="visualClear"></div>

Revision as of 22:33, 4 October 2013


Our Tutorials

During our iGEM summer we have learned some skills which are useful for iGEM and also for any synthetic biologist. In order to conservate and spread this knowledge we created some How To Tutorials. We hope that these Tutorials help iGEM teams in the future to present their project in a more colorful fashion.

Generation of Annimated Gifs showing PDB files in 3D

The generation of animated Gif from PDB files was done sice some time in the iGEM competition. Here we present an easy to reproduce tutorial for iGEMers which are interested in such figures.

  • If there is no PDB file availible for your protein of interest, you may use a homology search to find the most homologue structure. For this homology search you have to enter the amino acid sequece for example into [http://toolkit.tuebingen.mpg.de/hhpred HHpred]
  • The entry for the best matching structure was used for the figure. If it is only a homologous structure please cite this together with the homology when presenting the resulting Gif.
  • You can save the PDB file of the homologous structure on your computer
  • If you do not have [http://www.pymol.org/ PyMol] (freeware) installed on your computer download and install it.
  • Start PyMol software and open the PDB-file by clicking File>Open
  • The following approach was adapted from a PyMol-Tutorial http://ihome.cuhk.edu.hk/~b102142/pymol/pymol_tutorial.html Wong
  • The following commands were entered into the command line:

PyMOL> orient
PyMOL> hide everything, all
PyMOL> show cartoon, all
PyMol> bg_color white
click> Settings>Rendering>Shadows>Occlusion
PyMOL> color purple, ss h; color yellow, ss s; color green, ss ""
PyMOL> show surface, all
PyMOL> set transparency, 0.75
PyMOL> set surface_quality, 1 (command will prolongue the process significantly, you may skip it)
PyMOL> set ray_trace_frames=1 (command will prolongue the process significantly, you may skip it)
PyMOL> mset 1 x180
PyMOL> util.mroll 1,180
PyMOL> mpng frame

  • Afterward the *.png files were automatically converted to *.tif files using [http://www.xnview.com/de/xnconvert/ XnConvert]
  • The program [http://www.animake.de/gif-animation.htm Animake] was used to generate the annimated GIFs
    • The Animake software was started
    • A new working folder was generated (File>New) and the *.gif files were imported (Edit>Import_from_file)
    • The background was set to white (Annimation>Settings)
    • The range of colors was set to 256 (Edit>Select_all and Edit>Change_Color)
    • The size of the file has to be reduced in order to be able to upload it on the iGEM wiki. This can be done by clicking Edit>Change_size. We suggest a size of 320x240 px or even samler if the resulting Gif becomes to big.
    • Finally the annimated Gif can be saved in the programm format (.abp) and as Gif (File>Save_as)
    • If you have problems to upload the file on the iGEM server you may try a reduced size (e.g. 300x225 px)

This is how your protein of interest could look like:

Wiki tips & tricks

Below is a list of iGEM wiki related tips and tutorials for future teams.

Picture viewer

Maybe you have not noticed it yet, but if you clicked any of the pictures on our wiki, you were not redirected to the ugly wiki page of the file. Instead a nice picture viewer opened and after you closed it, you did not have to go back to the site you saw the picture on. To get the same effect on your wiki follow the steps listed below:

  • Get the files!
    We modified the original slimbox 2 viewer to work with the wiki and to not exceed the browser viewport, so it is recommended to use our versions, which can be found at Team:TU-Munich/TUM13_slimbox2.css and Team:TU-Munich/TUM13_slimbox2.js.
  • Embed the files in your wiki!
    The two files mentioned above and [http://jquery.com/ jQuery] have to be embedded on all the pages that should use the picture viewer.
  • Include the autoload code block!
    A bit of JavaScript code that attaches the viewer to the right pictures needs to be executed on all the pages that use it. This code attaches the picture viewer to all images on the page which are embedded with the [[File:xxx.png|thumb|caption]] wiki code and it adds the corresponding caption to the viewer.
$(document).ready(function(){
	$("div.thumbinner > a img").slimbox({/* Put custom options here */}, function(el) {
		url = el.src;
		if (url.indexOf('thumb') != -1) {
			url = url.substring(0, url.lastIndexOf('/'));
			url = url.replace('/thumb/', '/');
		}
		description = $(el).parents("div.thumbinner").children("div.thumbcaption").text();
		return [url, description];
	}, function(el) {
		return (this == el);
	});
});
  • Test it!
    Below is an example picture, click on it to see what the picture viewer looks like.
The logo of our project.

Slideshow

To create a good looking slideshow just follow the instructions below:

  • Embed the files in your wiki!
    The two files mentioned above and [http://jquery.com/ jQuery] have to be embedded on all the pages that should use the slideshow.
  • Include the initializing code block!
    A bit of JavaScript code that activates the slideshow needs to be executed on all the pages that use it. This code changes all unordered lists of the class bxslider into slideshows.
$(document).ready(function(){
	$('.bxslider').bxSlider({
		responsive: false,
		auto: true,
		autoHover: true
	});
});
  • Add the slideshow to the page!
    To add a slideshow just put the pictures you want to include in an unordered list like shown below:
<html>
<ul class="bxslider">
	<li><img src="https://static.igem.org/mediawiki/2013/9/97/TUM13_slider_team1.jpg" /></li>
	<li><img src="https://static.igem.org/mediawiki/2013/3/30/TUM13_slider_team2.jpg" /></li>
	<li><img src="https://static.igem.org/mediawiki/2013/3/30/TUM13_slider_moos.jpg" /></li>
	<li><img src="https://static.igem.org/mediawiki/2013/6/66/TUM13_slider_kampen.jpg" /></li>
</ul>
</html>
  • Test it!
    Below is an example picture, click on it to see how the slideshow looks.

Setting up a basic Arduino measuring device

Introduction

Since the Arduino Due was released in autumn 2012, this is the first IGEM-year this very powerful device can be used. We found it a useful supervising tool for short- and long-time experiments. It can be used in as well as outside the lab. The improvements that were made from Uno to Due are considerable.

It is capable of handling many things at once, such as a WiFi Shield, a Display, a SD-Card and multiple Sensors. At this point the Uno didn't match up any longer. To establish the usage of Arduino in IGEM even more we'd like to share our experiences and help you building up a basic device that can collect and view sensor data on its display and upload them to a server.

Part Description

  • Arduino Due
  • Arduino WiFi Shield
  • Mega MSD Shield
  • MI0283 Display
  • TSL2561 Light sensor
  • TSL2561 absorption curve
  • Water Sensor

Arduino Due

The Arduino Due is the most powerful Arduino board. It's underlying 32bit-processor is the Atmel SAM3X8E. Contrary to the other boards which run at 5V, a power supply of 3.3V is sufficiant. It was released in October 2012.

Data:

 84 Mhz	CPU Clock
 96 	KBytes of SRAM.
512 	KBytes of Flash memory. 
 54 	Digital I/O Pins
 12 	Analog Input Pins
  2 	(DAC)Analog Outputs Pins

Arduino WiFi Shield

The Arduino WiFi Shield is an attachable shield that provides Wireless LAN 802.11b/g to the Arduino. It scans and connects to networks and opens TCP and UDP sockets for data transfer. It also supports WEP and WPA2 encryption. It was released in August 2012. The WiFi Shield is fully supported by the Arduino Due and Arduino supplies a suitable stock WiFi-library. There is also an on-board SD-card socket to store received data. As the SD-card is accessible separately, it can also be used as a storage for any data generated by the Arduino. The SD-card socket is also supported by a stock library. The communication between Arduino Due and the WiFi Shield runs via an SPI/ICSP interface.

Pin usage:

Pin  4	SS for SD card (Slave Select)
Pin  7	Handshake between Arduino and WiFi Shield
Pin 10	SS for WiFi
Pin 74	SPI MISO (Master in, Slave out)
Pin 75	SPI MOSI (Master out, Slave in)
Pin 76	SPI SCK  (Serial clock)
    gnd
    3.3V
    5V

Watterott mega msd-shield

The mega msd-shield was designed by Watterott and consists of a couple of components. The components are one real time clock, one SD-card socket (we won't use), a small battery and a socket for a touch display. To get it ready to run, the shield must be assembled. The stackable headers and the quartz must be soldered to the board and the battery must be inserted. Unluckily the mega msd-shield and therefore also the MI0283QT-9 touch display don't come with a working library for the Arduino Due. The existing library only supports all boards up to the Arduino Uno. Therefore all libraries have to be rewritten. The touch display and the SD-card-slot communicate with the Arduino Due via SPI/ICSP. The real time clock transmit its data via I²C.

Pin usage:

Pin  4	SS for SD card
Pin  6	SS for the touch of the touch display
Pin  8	reset LCD
Pin  9	LCD LED
Pin 20	RTC (real time clock) 	I²C	SDA (Serial Data Line)
Pin 21	RTC  			I²C	SCL (Serial Clock)
Pin 25 SS (7) for the LCD (Workarround of the double usage of pin 7 by the WIFI Shield)
Pin 50	SPI MISO
Pin 51	SPI MOSI
Pin 52	SPI SCK
    gnd
    3.3V

Display MI0283QT-9

The MI0283QT-9 is a multicolor touch display. It comes already attached to a board, where only the pin headers are left to be soldered. Once assembled it can easily be plugged into the mega msd-shield. It has an on-board touch controller (TI ADS7846). The display size is 2.83"(43.2 x 57.6mm) with a resolution of 240x320. It supports 262k colors. The pin usage is already considered in the mega msd-shield description.

Light sensor TSL2561

The light sensor is a small, so called, breakout board. It is usually connected by wires instead of directly plugged to the Arduino. The light sensor has two photo-diodes on-board that measure visible and infrared light. Similar to the RTC, the TSL2561 is addressed via I²C. Once you get the I²C library working on your Arduino Due working it takes only little effort to integrate additional I²C devices. Just very few lines of the library have to be rewritten here. The photo-diodes can be addressed separately or both at one. Their output is already converted to Lux.

pin usage:

Pin 20	TSL2561		 	I²C	SDA (Serial Data Line)
Pin 21	TSL2561			I²C	SCL (Serial Clock)
    gnd
    3.3V

Temperature sensor DS18B20

The temperature sensor is embedded into a water proof cable. It is addressed via a One-Wire interface. The provided data are digital raw data, which need to be converted into degrees Celsius. Information about the conversion are given by the manufacturer. Similar to the I²C (TwoWire) bus, you only have to get the One-Wire interface working once. After that, you can easily set up One-Wire more devices. Again, just very few lines of the library have to be rewritten.

pin usage:

Pin 14 	One-Wire DS18B20 (pin was randomly chosen)
Pin gnd
Pin 3.3V

Water sensor

Setting up the water sensor is very easy. If and how much water the sensor registered can be measured via an analog pin.

pin usage:

Pin A5	Water sensor
    gnd
    3.3V

Photo-diodes

We disassembled a broken "Biorad 550"-photometer and recovered a halogen lamp, a small number of wavelength filters, three of eight photo-diodes and their fitting Resistors.

Tools

  • Breadboard
  • Soldering bolt
  • Solder

Assembly

Keep everything clear during your assembly. If you have different colored linking cables, always try to use the same color code. For example: brown cable for 3.3V etc. Troubleshooting can get nasty.

  • place your Arduino Due on your desk
  • connect ground and 3.3V to two different lines of you breadboard
  • connect the light sensor's ground and the 3.3V line
  • connect the sda line of your light sensor to pin 20 and scl to pin 21
  • connect the temperature sensor's ground and the 3.3V line
  • connect the signal line of your temp sensor via the breadbroad to pin 14
  • place a ~50kOhm resistor between the 3.3V line and the temps sensor's signal line on your breadboard
  • connect the water sensor to the ground and 3.3V line
  • connect the signal line of your water sensor to pin A5
  • voila! You are done with the basic connection of your three sensors. The next steps explain how to connect the WiFi shield, the msd shield and the display. You can connect all the sensors to the shield's and header's pins the same way, you connected them to the Arduino Due
  • first solder a short copper cable to the msd shield, connecting its pin 25 to pin 7
  • Then bend pin 7 and pin 4, so they don't connect to the WiFi shield's pins. Pin 4 would be a double usage of the msd shield's and the wifi shield's sd card. Pin 7 (lcd slave select) interferes with the wifi handshake pin
  • This is just an explanation of how the shield's sub-devices are connected. A deeper understanding of the following diagrams goes along with a deeper understanding of the program's source code and the additional libraries. All shields are of course connected to the Arduino Due's ground and 3.3V line
  • The yellow link shows the spi interface between Arduino Due and the WiFi shield
  • the thinner yellow lines are the WiFi handshake and the wifi slave select connections
  • the blue link is the sd reader's slave select
  • the green link represents the connection to the real time clock
  • the pink link represents the spi interface between the msd shield and the Arduino Due, required for the communication with the lcd and its touch functions (pins 50, 51 and pin 52)
  • 
lcd slave select, lcd reset and lcd LED
  • lcd's touch slave select
  • the power supply can be established with a 9V block battery
  • at last: an overview


Code

We strongly recommend the usage of Microsoft Visual Studio with the "visual micro" plugin. Microsoft Intellisense helps you a lot, when you are unfamiliar with the manufacturer provided libraries (automatic code completion). In order to compile the code properly you need the latest beta version of Arduino's software. In the visual micro settings choose the path to the Arduino IDE on your hard drive and disable "Upload using programmer". In the settings of the Arduino IDE, select "use external software".

Now you are ready to start programming. We'd like to share our code. Feel free to use, edit and play around with it!

#include "SPI.h" // SPI library (stock) #include "Wire.h" // TwoWire library (stock) sda-scl #include "DS1307.h" // Real time clock library (original library, slightly rewritten to fit the Due) #include "MI0283QT9.h" // LCD library (quite much had to be rewritten). Pins were changed, usage of Software SPI... quite a mess but it works great #include "ADS7846.h" // Touch controller (same story as at the lcd library) #include "Adafruit_TSL2561.h" // light sensor library (had to be rewritten in some parts to fit the Due) functions were added to correct the lux-output that wasn't always correct with the stock library #include "OneWire.h" // OneWire (I don't know, but I guess it's the stock library) #include "avr/dtostrf.h" // optional library to workaround some compatibility problems with the Due #include "math.h" // standard C-maths library #include "SD.h" // SD reader (stock) #include "WiFi.h" // (stock) #include "time.h" // standard C-time library DS1307 *rtc; // real time clock MI0283QT9 *lcd; ADS7846 *tscr; // the "touch" of the touchscreen OneWire *tempsen; Adafruit_TSL2561 *lightsen; WiFiClient *client; boolean lastConnected, firstrun=1; char c; uint8_t sea; // current value of seconds uint16_t counter=0,valueCounter[3]; // vlauecounter 0:Water 1:Temp 2:Light/IR float valueWater=0, valueTemp=0, valueLight=0, valueLightIR=0; // these are the sensor values that are avaredged over each time interval between the sending processes uint32_t valueTime=0; void initDisplay() // initialize the lcd display { lcd->led(100); // lights on 100% lcd->setOrientation(180); // flip screen orientation to 180° (optional) lcd->clear(COLOR_WHITE); tscr->service(); if(tscr->getPressure()>5) // Calibration on pressure { tscr->doCalibration(lcd); } lcd->printClear(); } void initLightSen() // initialize the light sensor { lightsen->setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); lightsen->enableAutoGain(true); lightsen->begin(); } void initWiFi() // initialize the WIFI { char buf[64]; uint8_t nonet; IPAddress ip; nonet=WiFi.scanNetworks(); sprintf(buf,"Number of Networks: %2i",nonet); // Output of up to 6 networks in your range + display lcd->drawText(10,15,buf,1,COLOR_BLACK,COLOR_WHITE); // All display outputs need to be written into a String or char-array before they can be passed to the lcd controller sprintf(buf,WiFi.SSID(0)); lcd->drawText(10,30,buf,1,COLOR_BLACK,COLOR_WHITE); sprintf(buf,WiFi.SSID(1)); lcd->drawText(10,45,buf,1,COLOR_BLACK,COLOR_WHITE); sprintf(buf,WiFi.SSID(2)); lcd->drawText(10,60,buf,1,COLOR_BLACK,COLOR_WHITE); sprintf(buf,WiFi.SSID(3)); lcd->drawText(10,75,buf,1,COLOR_BLACK,COLOR_WHITE); sprintf(buf,WiFi.SSID(4)); lcd->drawText(10,90,buf,1,COLOR_BLACK,COLOR_WHITE); WiFi.begin("YOURWIFI","YOURPASSWORD"); // Connection to a WIFI (feel free to change these settings) strcpy(buf,WiFi.SSID()); lcd->drawText(10,120,buf,1,COLOR_BLACK,COLOR_WHITE); // Output of the SSID (WIFI name) if the WiFi Shield was connected successfully ip=WiFi.localIP(); sprintf(buf,"%3i.%3i.%3i.%3i",ip[0],ip[1],ip[2],ip[3]); // Show the Arduino's IP address lcd->drawText(10,135,buf,1,COLOR_BLACK,COLOR_WHITE); while(tscr->getPressure()==0) // Idle until the touchscreen is pressed to continue { delay(20); tscr->service(); } lcd->clear(COLOR_WHITE); } void initPhoto() // Initialize the photodiodes { analogReadResolution(12); // Set the reading resolution and the pinmode pinMode(A0,INPUT); pinMode(A1,INPUT); pinMode(A1,INPUT); } void updateSenTemp(){ // get current temperature data byte data[12]; // array the incoming values should be stored to byte addr[8] = {0x28,0x1D,0xF1,0xB0,0x04,0x00,0x00,0x6B}; // OneWire temperature sensor address tempsen->reset(); // build up a connection and request data tempsen->select(addr); tempsen->write(0x44,1); tempsen->depower(); tempsen->reset(); tempsen->select(addr); tempsen->write(0xBE); for(byte z = 0; z < 9; z++) data[z] = tempsen->read(); // read out the return and store it byte per byte to the array unsigned int raw = (data[1] << 8) | data[0]; char buf[20],temp[8]; dtostrf(((float)raw / 16.0)-1.5,4,2,temp);// conversion of the raw data into degrees Celsius valueTemp=(float)((valueCounter[1]*valueTemp)+((float)raw / 16.0)-1.5)/(float)(valueCounter[1]+1); // Take the current temperature into account for the avaredged value valueCounter[1]++; strcat(temp,"C "); sprintf(buf, "temperature: "); // Display output strcat(buf,temp); lcd->drawText(10, 90, buf, 1, COLOR_BLACK, COLOR_WHITE); } void updateSenLight() // get current light values { char buf[32]; uint16_t lsbroadband,lsinfrared; // definition lightsen->getLuminosity(&lsbroadband,&lsinfrared); // the full function is implemented in the library lsbroadband=((float)lsbroadband*lightsen->getMultiplier()); lsinfrared=((float)lsinfrared*lightsen->getMultiplier()); // getMultipier is a function I added. I believe the developers just missed something out in their lib sprintf(buf, "complete: %5i lux ",lsbroadband); lcd->drawText(10, 60, buf, 1, COLOR_BLACK, COLOR_WHITE); // Display output sprintf(buf, "infrared: %5i lux ",lsinfrared); lcd->drawText(10, 75, buf, 1, COLOR_BLACK, COLOR_WHITE); valueLight=(((float)valueCounter[2]*valueLight)+(float)lsbroadband)/(float)(valueCounter[2]+1.0); // Calculate the avaredged values valueLightIR=(((float)valueCounter[2]*valueLightIR)+(float)lsinfrared)/(float)(valueCounter[2]+1.0); valueCounter[2]++; } void updateSenWater() // get current water values { char buf[20],wtr[7]; float water = (0.0009765625*(float)analogRead(A5)); // The water sensor doesn't really work lineary. Here is my approximation for correction. water = 1.0-water; water = -pow(water,7.0); water = pow(2.0,water); water = 200.0*(1-water); if(water>0) dtostrf(water,4,2,wtr); else { sprintf(wtr,"0.0"); water=0.0; } valueWater=((valueCounter[0]*valueWater)+water)/(valueCounter[0]+1); // avaredged value valueCounter[0]++; sprintf(buf,"Wasser: "); // Display output strcat(buf,wtr); strcat(buf," "); lcd->drawText(10, 105, buf, 1, COLOR_BLACK, COLOR_WHITE); } void updateTouch() // Register if someone touched the display { uint16_t pos; char buf[7]; tscr->service(); // some kind of flush-function. Gets the touchpads current state. pos=tscr->getX(); sprintf(buf,"X=%04i",pos); lcd->drawText(10,30,buf,1,COLOR_BLACK,COLOR_WHITE); // Display the x and y touch position pos=tscr->getY(); sprintf(buf,"Y=%04i",pos); lcd->drawText(10,45,buf,1,COLOR_BLACK,COLOR_WHITE); tscr->service(); } void updateRTC() // update the time from the clock { uint8_t se,mi,ho,da,mo; uint16_t yr; uint32_t unixtime; rtc->get(&se,&mi,&ho,&da,&mo,&yr); if(sea!=se) // Only refresh the values on the display if they changed (when the seconds value has changed since the last call) { char buf[24]; sprintf(buf,"%02i:%02i:%02i %02i.%02i:%04i",ho,mi,se,da,mo,yr); lcd->drawText(10,15,buf,1,COLOR_BLACK,COLOR_WHITE); sea=se; } struct tm t; // Calculate the unixtime from year, month and so on time_t t_of_day; t.tm_year=yr-1900; t.tm_mon=mo-1; t.tm_mday=da; t.tm_hour=ho; t.tm_min=mi; t.tm_sec=se; t_of_day = mktime(&t); valueTime=t_of_day; // pass the unixtime to the global variable } void updatePhoto(){ // update the photosensors (just an analogue readout) char buf[5]; sprintf(buf,"%04i",analogRead(A0)); lcd->drawText(10,120,buf,1,COLOR_BLACK,COLOR_WHITE); // Display output sprintf(buf,"%04i",analogRead(A1)); lcd->drawText(10,135,buf,1,COLOR_BLACK,COLOR_WHITE); sprintf(buf,"%04i",analogRead(A2)); lcd->drawText(10,150,buf,1,COLOR_BLACK,COLOR_WHITE); } void WifiDatasend(){ char key[] = "YOURKEY",url[] = "http://igem.yourwebsite.com/save.php"; // key and url to your php-save-script (feel free to change) if(firstrun) { delay(1000); // fix, because there are no good values on the first run firstrun=0; return; } if (client->connect("igem.yourwebsite.com", 80)) // build up a conntection to the server on port 80 (feel free to change) { Serial.println("Connected, Sending Data..."); client->println("GET " + String(url) + "?key=" + String(key) + "&water="+String(valueWater,3) + "&temp="+String(valueTemp,3) + "&light1="+String(valueLight,3) + "&light2="+String(valueLightIR,3) +"&time="+String(valueTime)); Serial.println("GET " + String(url) + "?key=" + String(key) + "&water="+String(valueWater,3) + "&temp="+String(valueTemp,3) + "&light1="+String(valueLight,3) + "&light2="+String(valueLightIR,3) +"&time="+String(valueTime)); client->println("Connection: close"); Serial.println("Connection: close"); } else { Serial.println("***** CONNECTION FAILED *****"); } for(int i=0;i<3;i++) valueCounter[i]=0; // Reset all counters and values for the avaredging process valueWater=0.0; valueTemp=0.0; valueLight=0.0; valueLightIR=0.0; } void WifiDataReceive() { int i=0; while (client->connected() && i++<200) // Read out the servers response and pass it to the Serial output (needs connection to a PC) { if(client->available()) { while (client->available()) { char response = client->read(); Serial.print(response); } i=200; } else delay(1); } if(i==200) Serial.println(); } // Here are the main functions that are called by the arduino. // All devices had to be defined as pointers and initialized in the setup function due to compiler issues with the Arduino Due. // The usage of the Arduino Due isn't quite established and the arduino software has still some room for improvement here. // Setup is called once at the startup and at each reset // All called functions are commented and explained in detail above ;) void setup() { lightsen = new Adafruit_TSL2561(TSL2561_ADDR_FLOAT,12345); lcd = new MI0283QT9(); rtc = new DS1307(); tscr = new ADS7846(); tempsen = new OneWire(14); client = new WiFiClient(); pinMode(A5,INPUT); // Pin A5 is an analogue input lastConnected = false; Serial.begin(9600); SD.begin(4); rtc->start(); lcd->init(); tscr->init(); initDisplay(); initLightSen(); initPhoto(); initWiFi(); } // The if(counter%xx==0) code functions as some kind of process handler. Some functions should be called more often than others. // at each run there is a delay of 1ms and a value of '1' is added to the counter. Most of the functions hardly take any time. // But some are quite time-consuming. // The % operator is the modulo. At counter%7==0 the function is called every 7th run. // For example the functions WifiDatasend and -Receive, which don't have to be called that often. They are executed every 1000th/5000th time. void loop() { if(counter%29==0) updateRTC(); if(counter%7==0) updateTouch(); if(counter%503==0) updateSenTemp(); if(counter%197==0) {updateSenLight();updatePhoto();}; if(counter%457==0) updateSenWater(); if(counter%5000==0) WifiDatasend(); if(counter%1000==1) WifiDataReceive(); if(counter%5000==4300) // Around 700 ms before the data will be sent the Arduino breaks up the old connection to the server { client->stop(); Serial.println("Done."); client->flush(); } counter++; delay(1); }