├── README.md ├── banner.jpg ├── diagram1.png ├── diagram2.png ├── example ├── basic_test │ ├── ESP_MICRO.h │ ├── basic_test.ino │ └── python_reader.py ├── ledControl │ ├── ESP_MICRO.h │ ├── ledControl.ino │ └── led_controller.py └── readSensor │ ├── ESP_MICRO.h │ ├── python_reader.py │ └── readSensor.ino └── library ├── ESP_MICRO.h └── EXAMPLE_PYTHON_READER.py /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266 to PY 2 | It helps you to pull data from esp8266 and command it trough py. [Tutorial here.](https://www.instructables.com/id/ESP8266-and-Python-Communication-ForNoobs/) 3 | 4 | # Requirements 5 | Python lib: 6 | - urllib.request *(generally internal lib)* 7 | 8 | Arduino lib: 9 | - [esp8266 card library](https://arduino-esp8266.readthedocs.io/en/2.4.1/installing.html) 10 | 11 | ## System diagram 12 | ![diagram](diagram1.png) 13 | [Different visual version if you didn't understand.](diagram2.png) 14 | 15 | # How to use this micro lib 16 | Just import `ESP_MICRO.h` and use send / control / return functions for your project. 17 | 18 | ## start( ssid, pass) 19 | You simply enter your wifi details into this function and it starts the connection. 20 | 21 | ## waitUntilNewReq( ) 22 | It's just a time block that waits for a request. It gives you the full control over python. With this ESP will wait until a python request come. 23 | 24 | ## returnThisStr( ) & returnThisInt( ) 25 | Finally, you can return the desired data (or simply sensor data) to localhost server. 26 | 27 | ## getPath() 28 | In order to command ESP trough py we also have a string returning function `getPath()`, it simply reads get request: 29 | Useful with interacting and controlling the system. 30 | 31 | `py: GET example.com/OPEN_LED 32 | esp: 33 | if (getPath()=="/OPEN_LED"){ 34 | digitalWrite(LED,HIGH); 35 | } 36 | ` 37 | 38 | # Important (Getting ESP's IP adress) 39 | While uploading the code, check serial port for ESP's local IP if you don't know how to use nmap or obtain ESP's IP, it'll be printed. 40 | 41 | 42 | # Reminder 43 | - It's fork of [mDNSserver example](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS) by [Ivan Grokhotkov](https://github.com/igrr) 44 | 45 | ### Deficiencies 46 | - ~~The code is a bit complex, will be simplified.~~ 47 | - ~~Needs a tutorial ~~ [(Tutorial here)](https://www.instructables.com/id/ESP8266-and-Python-Communication-ForNoobs/) 48 | -------------------------------------------------------------------------------- /banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KebabLord/esp2python/b0953c1babeed08a91dbf33798bef40f2ff521d5/banner.jpg -------------------------------------------------------------------------------- /diagram1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KebabLord/esp2python/b0953c1babeed08a91dbf33798bef40f2ff521d5/diagram1.png -------------------------------------------------------------------------------- /diagram2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KebabLord/esp2python/b0953c1babeed08a91dbf33798bef40f2ff521d5/diagram2.png -------------------------------------------------------------------------------- /example/basic_test/ESP_MICRO.h: -------------------------------------------------------------------------------- 1 | /* ESP8266 TO PY: THE MICRO LIBRARY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | 5 | * MAP 6 | - start(ssid,password)---> Connects to wifi with given username and password 7 | - waitUntilNewReq() -----> Waits until a new python request come, checks for requests regularly 8 | - returnThisInt(data) ---> sends your Integer data to localhost (python) 9 | - returnThisStr(data) ---> sends your String data to localhost (python) 10 | - getPath() -------------> gets the request path as string, ex: https://192.113.133/ledON -> "ledON" 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | // PORT 18 | WiFiServer server(80); 19 | WiFiClient client; 20 | String rule; 21 | 22 | void start(String ssid, String pass){ 23 | WiFi.mode(WIFI_STA); 24 | WiFi.begin(ssid.c_str(),pass.c_str()); 25 | 26 | Serial.println(""); 27 | // Wait for connection 28 | while (WiFi.status() != WL_CONNECTED) { 29 | delay(500); 30 | Serial.print("."); 31 | } 32 | Serial.println(""); 33 | Serial.print("Connected to "); 34 | Serial.println(ssid); 35 | Serial.print("IP address: "); 36 | Serial.println(WiFi.localIP()); 37 | // Setting up mDNS responder 38 | if (!MDNS.begin("esp8266")) { 39 | Serial.println("Error setting up MDNS responder!"); 40 | while (1) { 41 | delay(1000); 42 | } 43 | } 44 | Serial.println("mDNS responder started"); 45 | // Start TCP (HTTP) server 46 | server.begin(); 47 | Serial.println("TCP server started"); 48 | // Add service to MDNS-SD 49 | MDNS.addService("http", "tcp", 80); 50 | } 51 | 52 | bool isReqCame = false; 53 | 54 | void CheckNewReq(){ 55 | client = server.available(); 56 | if (!client) { 57 | return; 58 | } 59 | Serial.println(""); 60 | Serial.println("NEW REQUEST"); 61 | // Waiting client to connect 62 | while (client.connected() && !client.available()) { 63 | delay(1); 64 | } 65 | // Read the first line of HTTP request 66 | String req = client.readStringUntil('\r'); 67 | int addr_start = req.indexOf(' '); 68 | int addr_end = req.indexOf(' ', addr_start + 1); 69 | if (addr_start == -1 || addr_end == -1) { 70 | Serial.print("Invalid request: "); 71 | Serial.println(req); 72 | return; 73 | } 74 | req = req.substring(addr_start + 1, addr_end); 75 | Serial.print("Requested Path: "); 76 | Serial.println(req); 77 | 78 | rule = req; 79 | isReqCame = true; 80 | client.flush(); 81 | } 82 | void waitUntilNewReq(){ 83 | do {CheckNewReq();} while (!isReqCame); 84 | isReqCame = false; 85 | } 86 | 87 | void returnThisStr(String final_data){ 88 | String s; 89 | //HTTP Protocol code. 90 | s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; 91 | s += final_data; //Our final raw data to return 92 | client.print(s); 93 | Serial.println("Returned to client."); 94 | } 95 | void returnThisInt(int final_data){ 96 | returnThisStr(String(final_data)); 97 | } 98 | 99 | String getPath(){ 100 | return rule; 101 | } 102 | -------------------------------------------------------------------------------- /example/basic_test/basic_test.ino: -------------------------------------------------------------------------------- 1 | /* BASIC_TEST FOR ESP2PY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | * 5 | * It simply returns the variable "index" to python and 6 | increases it everytime a python request came 7 | */ 8 | 9 | #include "ESP_MICRO.h" 10 | 11 | int index = 0; 12 | 13 | void setup(){ 14 | Serial.begin(9600); 15 | start("WIFI SSID","PASSWORD");// Connect to wifi, enter your details here 16 | } 17 | 18 | void loop(){ 19 | waitUntilNewReq(); // Waits until a new request from python come 20 | indeks += 1; 21 | returnThisInt(indeks); // Returns the data to python 22 | } 23 | -------------------------------------------------------------------------------- /example/basic_test/python_reader.py: -------------------------------------------------------------------------------- 1 | """ PY READER FROM ESP """ 2 | # Written by Junicchi - https://github.com/Kebablord 3 | 4 | from time import sleep 5 | import urllib.request 6 | url = "http://ENTER ESP'S IP ADRESS HERE" # ESP's IP, ex: http://192.168.102/ (Check serial console while uploading the ESP code, the IP will be printed) 7 | 8 | def get_data(): 9 | global data 10 | 11 | n = urllib.request.urlopen(url).read() # get the raw html data in bytes (sends request and warn our esp8266) 12 | n = n.decode("utf-8") # convert raw html bytes format to string :3 13 | 14 | data = n 15 | # data = n.split() # split datas we got. (if you programmed it to send more than one value) It splits them into seperate list elements. 16 | # data = list(map(int, data)) # turn datas to integers, now all list elements are integers. 17 | 18 | # Example usage 19 | while True: 20 | get_data() 21 | print("Your data(s) which we received from ESP: "+data) 22 | sleep(1) 23 | -------------------------------------------------------------------------------- /example/ledControl/ESP_MICRO.h: -------------------------------------------------------------------------------- 1 | /* ESP8266 TO PY: THE MICRO LIBRARY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | 5 | * MAP 6 | - start(ssid,password)---> Connects to wifi with given username and password 7 | - waitUntilNewReq() -----> Waits until a new python request come, checks for requests regularly 8 | - returnThisInt(data) ---> sends your Integer data to localhost (python) 9 | - returnThisStr(data) ---> sends your String data to localhost (python) 10 | - getPath() -------------> gets the request path as string, ex: https://192.113.133/ledON -> "ledON" 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | // PORT 18 | WiFiServer server(80); 19 | WiFiClient client; 20 | String rule; 21 | 22 | void start(String ssid, String pass){ 23 | WiFi.mode(WIFI_STA); 24 | WiFi.begin(ssid.c_str(),pass.c_str()); 25 | 26 | Serial.println(""); 27 | // Wait for connection 28 | while (WiFi.status() != WL_CONNECTED) { 29 | delay(500); 30 | Serial.print("."); 31 | } 32 | Serial.println(""); 33 | Serial.print("Connected to "); 34 | Serial.println(ssid); 35 | Serial.print("IP address: "); 36 | Serial.println(WiFi.localIP()); 37 | // Setting up mDNS responder 38 | if (!MDNS.begin("esp8266")) { 39 | Serial.println("Error setting up MDNS responder!"); 40 | while (1) { 41 | delay(1000); 42 | } 43 | } 44 | Serial.println("mDNS responder started"); 45 | // Start TCP (HTTP) server 46 | server.begin(); 47 | Serial.println("TCP server started"); 48 | // Add service to MDNS-SD 49 | MDNS.addService("http", "tcp", 80); 50 | } 51 | 52 | bool isReqCame = false; 53 | 54 | void CheckNewReq(){ 55 | client = server.available(); 56 | if (!client) { 57 | return; 58 | } 59 | Serial.println(""); 60 | Serial.println("NEW REQUEST"); 61 | // Waiting client to connect 62 | while (client.connected() && !client.available()) { 63 | delay(1); 64 | } 65 | // Read the first line of HTTP request 66 | String req = client.readStringUntil('\r'); 67 | int addr_start = req.indexOf(' '); 68 | int addr_end = req.indexOf(' ', addr_start + 1); 69 | if (addr_start == -1 || addr_end == -1) { 70 | Serial.print("Invalid request: "); 71 | Serial.println(req); 72 | return; 73 | } 74 | req = req.substring(addr_start + 1, addr_end); 75 | Serial.print("Requested Path: "); 76 | Serial.println(req); 77 | 78 | rule = req; 79 | isReqCame = true; 80 | client.flush(); 81 | } 82 | void waitUntilNewReq(){ 83 | do {CheckNewReq();} while (!isReqCame); 84 | isReqCame = false; 85 | } 86 | 87 | void returnThisStr(String final_data){ 88 | String s; 89 | //HTTP Protocol code. 90 | s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; 91 | s += final_data; //Our final raw data to return 92 | client.print(s); 93 | Serial.println("Returned to client."); 94 | } 95 | void returnThisInt(int final_data){ 96 | returnThisStr(String(final_data)); 97 | } 98 | 99 | String getPath(){ 100 | return rule; 101 | } 102 | -------------------------------------------------------------------------------- /example/ledControl/ledControl.ino: -------------------------------------------------------------------------------- 1 | /* LED CONTROLLING WITH PYTHON 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | * 5 | * It's a ESP management through Python example 6 | * It simply fetches the path from the request 7 | * Path is: https://example.com/this -> "/this" 8 | * You can command your esp through python with request paths 9 | * You can read the path with getPath() function 10 | */ 11 | 12 | 13 | #include "ESP_MICRO.h" 14 | 15 | #define LED 4 16 | 17 | void setup(){ 18 | Serial.begin(9600); 19 | start("Username","Password"); // Wifi details connec to 20 | 21 | pinMode(LED,OUTPUT); 22 | } 23 | 24 | void loop(){ 25 | waitUntilNewReq(); //Waits until a new request from python come 26 | 27 | if (getPath()=="/OPEN_LED"){ 28 | digitalWrite(LED,HIGH); 29 | } 30 | if (getPath()=="/CLOSE_LED"){ 31 | digitalWrite(LED,LOW); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/ledControl/led_controller.py: -------------------------------------------------------------------------------- 1 | """ PY TO ESP (LED CONTROLLER) """ 2 | # Written by Junicchi - https://github.com/Kebablord 3 | 4 | import urllib.request 5 | root_url = "http://IP-ADRESS-OF-ESP" # ESP's url, ex: http://192.168.102 (Esp prints it to serial console when connected to wifi) 6 | 7 | def sendRequest(url): 8 | n = urllib.request.urlopen(url) # send request to ESP 9 | 10 | # Example usage 11 | while True: 12 | answer = input(""" To control the led, type "ON" or "OFF": """) 13 | if (answer=="ON"): 14 | sendRequest(root_url+"/OPEN_LED") 15 | print("Opened!\n\n") 16 | if (answer=="OFF"): 17 | sendRequest(root_url+"/CLOSE_LED") 18 | print("Closed!\n\n") 19 | -------------------------------------------------------------------------------- /example/readSensor/ESP_MICRO.h: -------------------------------------------------------------------------------- 1 | /* ESP8266 TO PY: THE MICRO LIBRARY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | 5 | * MAP 6 | - start(ssid,password)---> Connects to wifi with given username and password 7 | - waitUntilNewReq() -----> Waits until a new python request come, checks for requests regularly 8 | - returnThisInt(data) ---> sends your Integer data to localhost (python) 9 | - returnThisStr(data) ---> sends your String data to localhost (python) 10 | - getPath() -------------> gets the request path as string, ex: https://192.113.133/ledON -> "ledON" 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | // PORT 18 | WiFiServer server(80); 19 | WiFiClient client; 20 | String rule; 21 | 22 | void start(String ssid, String pass){ 23 | WiFi.mode(WIFI_STA); 24 | WiFi.begin(ssid.c_str(),pass.c_str()); 25 | 26 | Serial.println(""); 27 | // Wait for connection 28 | while (WiFi.status() != WL_CONNECTED) { 29 | delay(500); 30 | Serial.print("."); 31 | } 32 | Serial.println(""); 33 | Serial.print("Connected to "); 34 | Serial.println(ssid); 35 | Serial.print("IP address: "); 36 | Serial.println(WiFi.localIP()); 37 | // Setting up mDNS responder 38 | if (!MDNS.begin("esp8266")) { 39 | Serial.println("Error setting up MDNS responder!"); 40 | while (1) { 41 | delay(1000); 42 | } 43 | } 44 | Serial.println("mDNS responder started"); 45 | // Start TCP (HTTP) server 46 | server.begin(); 47 | Serial.println("TCP server started"); 48 | // Add service to MDNS-SD 49 | MDNS.addService("http", "tcp", 80); 50 | } 51 | 52 | bool isReqCame = false; 53 | 54 | void CheckNewReq(){ 55 | client = server.available(); 56 | if (!client) { 57 | return; 58 | } 59 | Serial.println(""); 60 | Serial.println("NEW REQUEST"); 61 | // Waiting client to connect 62 | while (client.connected() && !client.available()) { 63 | delay(1); 64 | } 65 | // Read the first line of HTTP request 66 | String req = client.readStringUntil('\r'); 67 | int addr_start = req.indexOf(' '); 68 | int addr_end = req.indexOf(' ', addr_start + 1); 69 | if (addr_start == -1 || addr_end == -1) { 70 | Serial.print("Invalid request: "); 71 | Serial.println(req); 72 | return; 73 | } 74 | req = req.substring(addr_start + 1, addr_end); 75 | Serial.print("Requested Path: "); 76 | Serial.println(req); 77 | 78 | rule = req; 79 | isReqCame = true; 80 | client.flush(); 81 | } 82 | void waitUntilNewReq(){ 83 | do {CheckNewReq();} while (!isReqCame); 84 | isReqCame = false; 85 | } 86 | 87 | void returnThisStr(String final_data){ 88 | String s; 89 | //HTTP Protocol code. 90 | s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; 91 | s += final_data; //Our final raw data to return 92 | client.print(s); 93 | Serial.println("Returned to client."); 94 | } 95 | void returnThisInt(int final_data){ 96 | returnThisStr(String(final_data)); 97 | } 98 | 99 | String getPath(){ 100 | return rule; 101 | } 102 | -------------------------------------------------------------------------------- /example/readSensor/python_reader.py: -------------------------------------------------------------------------------- 1 | """ ESP8266 TO PY: READER """ 2 | # Written by Junicchi - https://github.com/Kebablord 3 | 4 | import urllib.request 5 | url = "http://IP-ADRESS-OF-ESP" # ESP's IP, ex: http://192.168.102 (Esp prints it to serial console when connected to wifi) 6 | 7 | def get_data(): 8 | global data 9 | 10 | n = urllib.request.urlopen(url).read() # get the raw html data in bytes (sends request and warn our esp8266) 11 | n = n.decode("utf-8") # convert raw html bytes format to string :3 12 | 13 | data = n 14 | # data = n.split() # split datas we got. (if you programmed it to send more than one value) It splits them into seperate list elements. 15 | # data = list(map(int, data)) # turn datas to integers, now all list elements are integers. 16 | 17 | # Example usage 18 | while True: 19 | get_data() 20 | print("Your data(s) which we received from arduino: "+data) 21 | input("To test it again press enter.") 22 | -------------------------------------------------------------------------------- /example/readSensor/readSensor.ino: -------------------------------------------------------------------------------- 1 | /* PING -> ESP TO PY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | * 5 | * Reads the value of Ping Sensor and returns it to Python 6 | * This example is written for Nodemcu Cards 7 | */ 8 | 9 | #include "ESP_MICRO.h" // importing our library 10 | 11 | #define TRIG_PIN 4 12 | #define ECHO_PIN 5 13 | long duration; 14 | int distance; 15 | 16 | void setup(){ 17 | Serial.begin(9600); 18 | start("USERNAME","PASSWORD"); // Wifi details connect to 19 | 20 | pinMode(TRIG_PIN, OUTPUT); 21 | pinMode(ECHO_PIN, INPUT); 22 | } 23 | 24 | void loop(){ 25 | waitUntilNewReq(); //Waits until a new request from python come 26 | 27 | digitalWrite(TRIG_PIN, LOW); 28 | delayMicroseconds(2); 29 | digitalWrite(TRIG_PIN, HIGH); 30 | delayMicroseconds(10); 31 | digitalWrite(TRIG_PIN, LOW); 32 | 33 | // Read the returned wave 34 | duration = pulseIn(ECHO_PIN, HIGH); 35 | // Calculate the delay into cm 36 | distance = duration*0.034/2; 37 | 38 | returnThisInt(distance); //Returns the data to python 39 | } 40 | -------------------------------------------------------------------------------- /library/ESP_MICRO.h: -------------------------------------------------------------------------------- 1 | /* ESP8266 TO PY: THE MICRO LIBRARY 2 | * Written by Junicchi 3 | * https://github.com/Kebablord 4 | 5 | * MAP 6 | - start(ssid,password)---> Connects to wifi with given username and password 7 | - waitUntilNewReq() -----> Waits until a new python request come, checks for requests regularly 8 | - returnThisInt(data) ---> sends your Integer data to localhost (python) 9 | - returnThisStr(data) ---> sends your String data to localhost (python) 10 | - getPath() -------------> gets the request path as string, ex: https://192.113.133/ledON -> "ledON" 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | // PORT 18 | WiFiServer server(80); 19 | WiFiClient client; 20 | String rule; 21 | 22 | void start(String ssid, String pass){ 23 | WiFi.mode(WIFI_STA); 24 | WiFi.begin(ssid.c_str(),pass.c_str()); 25 | 26 | Serial.println(""); 27 | // Wait for connection 28 | while (WiFi.status() != WL_CONNECTED) { 29 | delay(500); 30 | Serial.print("."); 31 | } 32 | Serial.println(""); 33 | Serial.print("Connected to "); 34 | Serial.println(ssid); 35 | Serial.print("IP address: "); 36 | Serial.println(WiFi.localIP()); 37 | // Setting up mDNS responder 38 | if (!MDNS.begin("esp8266")) { 39 | Serial.println("Error setting up MDNS responder!"); 40 | while (1) { 41 | delay(1000); 42 | } 43 | } 44 | Serial.println("mDNS responder started"); 45 | // Start TCP (HTTP) server 46 | server.begin(); 47 | Serial.println("TCP server started"); 48 | // Add service to MDNS-SD 49 | MDNS.addService("http", "tcp", 80); 50 | } 51 | 52 | bool isReqCame = false; 53 | 54 | void CheckNewReq(){ 55 | client = server.available(); 56 | if (!client) { 57 | return; 58 | } 59 | Serial.println(""); 60 | Serial.println("NEW REQUEST"); 61 | // Waiting client to connect 62 | while (client.connected() && !client.available()) { 63 | delay(1); 64 | } 65 | // Read the first line of HTTP request 66 | String req = client.readStringUntil('\r'); 67 | int addr_start = req.indexOf(' '); 68 | int addr_end = req.indexOf(' ', addr_start + 1); 69 | if (addr_start == -1 || addr_end == -1) { 70 | Serial.print("Invalid request: "); 71 | Serial.println(req); 72 | return; 73 | } 74 | req = req.substring(addr_start + 1, addr_end); 75 | Serial.print("Requested Path: "); 76 | Serial.println(req); 77 | 78 | rule = req; 79 | isReqCame = true; 80 | client.flush(); 81 | } 82 | void waitUntilNewReq(){ 83 | do {CheckNewReq();} while (!isReqCame); 84 | isReqCame = false; 85 | } 86 | 87 | void returnThisStr(String final_data){ 88 | String s; 89 | //HTTP Protocol code. 90 | s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; 91 | s += final_data; //Our final raw data to return 92 | client.print(s); 93 | Serial.println("Returned to client."); 94 | } 95 | void returnThisInt(int final_data){ 96 | returnThisStr(String(final_data)); 97 | } 98 | 99 | String getPath(){ 100 | return rule; 101 | } 102 | -------------------------------------------------------------------------------- /library/EXAMPLE_PYTHON_READER.py: -------------------------------------------------------------------------------- 1 | """ EXAMPLE PY READER FROM ESP """ 2 | # Written by Junicchi - https://github.com/Kebablord 3 | 4 | import urllib.request 5 | url = "IP-ADRESS-URL-OF-ESP-SERVER" # ESP's url, ex: https://192.168.102/ (Esp serial prints it when connected to wifi) 6 | 7 | def get_data(): 8 | global data 9 | 10 | n = urllib.request.urlopen(url).read() # get the raw html data in bytes (sends request and warn our esp8266) 11 | n = n.decode("utf-8") # convert raw html bytes format to string :3 12 | 13 | data = n 14 | # data = n.split() # split datas we got. (if you programmed it to send more than one value) It splits them into seperate list elements. 15 | # data = list(map(int, data)) # turn datas to integers, now all list elements are integers. 16 | 17 | # Example usage 18 | while True: 19 | get_data() 20 | print("Your data(s) which we received from arduino: "+data) 21 | input("To test it again press enter.") 22 | --------------------------------------------------------------------------------